outbound-engine
The problem this solves: you're paying for a $700+/mo prospecting stack (Apollo,
Hunter.io, whatever else) to do something you could be doing from signals you
already have — who's visiting your site and looking like a buyer. One AMM member
(Bryan Fikes) already solved this for himself: Smartlead + LinkedIn Sales
Navigator + Visual Visitor + his own website + the Search Atlas MCP, no Apollo,
no Hunter, 34% cold-email open rate, real sales calls booked. This tool
packages that shape — signal in, scored + enriched, personalized draft out,
you approve, it loads to your outreach platform — so a second member can run
it without reverse-engineering his setup.
What it isn't: an auto-send bot. Every draft this produces sits in a review
queue until you approve, edit, or reject it. And in this specific build, even
the "load to Smartlead" step is a dry-run preview — it shows you the exact
payload that would go out, and calls nothing.
Say this to your agent
"Run my outbound pipeline." (or: "Build my ICP for the outbound engine." / "Show
me my outbound review queue." / "Generate my weekly outbound report.")
That's the whole interaction model. Underneath, the agent runs:
cd tools/outbound-engine
python3 run.py pipeline --dry-run # signals -> enrich -> personalize
python3 run.py review # approve / edit / skip / reject, interactively
python3 run.py load --dry-run # preview what WOULD load to Smartlead
python3 run.py report # weekly HTML report
If config/icp.yaml doesn't exist yet, run python3 run.py wizard first — a
short guided interview that builds it.
The pattern (five stages, one review gate)
- Signals — pull recent website-visitor hits (company, page visited, visit
count, referrer type, and a named contact if your signal source resolved one).
v1 ships exactly one signal source.
- Enrich — score each hit against your ICP: industry match, trigger-signal
strength (which page, how many visits, paid vs. organic), hard excludes
(competitor agencies,
.edu domains, your own current clients). This step
is plain deterministic logic, not an LLM call — you can read exactly why a
prospect got the score it did.
- Personalize — draft a short outreach email per non-rejected prospect,
using your own voice examples as a style reference only — never copied
verbatim, never inventing facts about the prospect that aren't in its record.
- Review (the gate) — every draft is
pending_review. You approve, edit,
skip, or reject each one before it goes anywhere. This is not optional and
not skippable by config — it's the shape of the tool.
- Load + Report — approved drafts get built into the exact payload your
outreach platform would need; the weekly report shows what moved through
the pipeline and (once live) what it produced.
Why this build never actually sends anything
Two separate reasons, either one alone would be enough:
- This build's own rule. Real external-send wiring — a live Visual Visitor
pull, a live Smartlead POST — is a JD-approval matter, not something enabled
during a build. So
signals/visual_visitor.py and load/smartlead.py ship
as mock/dry-run-only, on purpose, with a LiveModeNotImplementedError that
fires if you (or an .env file) tries to flip a live-mode flag.
- An open wiring question. The product spec for this tool explicitly calls
for getting Bryan Fikes' field-by-field wiring — his exact Visual Visitor
plan/API, contact-enrichment setup, and Smartlead campaign structure — in a
30-minute call before writing the real adapters, so the tool packages his
actual reality instead of a plausible-looking guess. That call hasn't
happened yet. See
README.md's "Live mode" section and the docstrings at
the top of signals/visual_visitor.py and load/smartlead.py for the full
detail, including exactly what's needed before either adapter can go live.
None of this blocks using the tool today — the whole pipeline (scoring,
drafting, the review queue, the report) is real, tested, and runnable; only
the two outermost edges (pulling real visitor data, pushing a real send) are
intentionally stubbed.
What a good result looks like
- You get a short list of prospects that actually match your ICP, each with a
plain-English reason they surfaced — not a firehose of everyone who touched
your site.
- Every draft you see in the review queue reads like something you'd actually
send, references the real reason the prospect showed up, and never claims a
stat or fact that isn't in the prospect's record.
- Nothing leaves your review queue without your explicit approve/edit — the
tool cannot send on your behalf even if you wanted it to, in this build.
- The weekly report tells you honestly what's real (prospects surfaced,
drafted, approved) vs. what's a placeholder until live sending is wired
(opens, replies, calls booked all read "n/a — dry-run build" rather than a
made-up number).
How it pairs with the other Founding Circle tools
bug-hunter and this tool share the same "find-and-report first, dry-run
before any write" posture that SECURITY.md requires of anything touching a
live account or an outbound send.
client-dashboard is the natural next step once real sending is live —
a client-safe weekly view of pipeline/booked-call numbers, never the
machinery behind them.
connection-monitor is worth putting on top of this once it's live: the
moment a Smartlead or Visual Visitor connection silently drops, you want a
ping, not a week of an empty pipeline you didn't notice.
Where things land
| File |
What it is |
SKILL.md |
This walkthrough. |
README.md |
Full setup, run commands, and the detailed "why dry-run" explanation. |
.env.example |
Copy to .env — keys never leave your machine; live-mode flags are refused on purpose in this build. |
run.py |
CLI entrypoint (wizard, signals, enrich, personalize, review, load, report, pipeline). |
config/icp.example.yaml |
Copy to config/icp.yaml, or build it via python3 run.py wizard. |
config/voice-examples.example.md |
Copy to config/voice-examples.md and paste in 2-3 real emails that got a good reply. |
outbound_engine/ |
The pipeline code — see README.md's file map for the module-by-module breakdown. |
tests/ |
pytest, fully offline — run python -m pytest tests/ from this folder. |
1---2name: outbound-engine3description: Run a prospecting pipeline that finds website visitors who look like real buyers, scores them against your ICP, drafts a personalized cold email, and queues it for your approval — before anything ever touches a real send. Packages the proven website-visitor-to-Smartlead stack an AMM member built that replaced a ~$700/mo Apollo + Hunter.io spend. Use when you want to run your outbound pipeline, review pending outreach drafts, build your Ideal Customer Profile, or generate a weekly pipeline report. This build is dry-run only — it never sends a real email or calls a real Visual Visitor/Smartlead API.4---56# outbound-engine78**The problem this solves:** you're paying for a $700+/mo prospecting stack (Apollo,9Hunter.io, whatever else) to do something you could be doing from signals you10already have — who's visiting your site and looking like a buyer. One AMM member11(Bryan Fikes) already solved this for himself: Smartlead + LinkedIn Sales12Navigator + Visual Visitor + his own website + the Search Atlas MCP, no Apollo,13no Hunter, **34% cold-email open rate, real sales calls booked.** This tool14packages that shape — signal in, scored + enriched, personalized draft out,15you approve, it loads to your outreach platform — so a second member can run16it without reverse-engineering his setup.1718**What it isn't:** an auto-send bot. Every draft this produces sits in a review19queue until you approve, edit, or reject it. And in this specific build, even20the "load to Smartlead" step is a dry-run preview — it shows you the exact21payload that *would* go out, and calls nothing.2223---2425## Say this to your agent2627> "Run my outbound pipeline." (or: "Build my ICP for the outbound engine." / "Show28> me my outbound review queue." / "Generate my weekly outbound report.")2930That's the whole interaction model. Underneath, the agent runs:3132```bash33cd tools/outbound-engine34python3 run.py pipeline --dry-run # signals -> enrich -> personalize35python3 run.py review # approve / edit / skip / reject, interactively36python3 run.py load --dry-run # preview what WOULD load to Smartlead37python3 run.py report # weekly HTML report38```3940If `config/icp.yaml` doesn't exist yet, run `python3 run.py wizard` first — a41short guided interview that builds it.4243---4445## The pattern (five stages, one review gate)46471. **Signals** — pull recent website-visitor hits (company, page visited, visit48 count, referrer type, and a named contact if your signal source resolved one).49 v1 ships exactly one signal source.502. **Enrich** — score each hit against your ICP: industry match, trigger-signal51 strength (which page, how many visits, paid vs. organic), hard excludes52 (competitor agencies, `.edu` domains, your own current clients). This step53 is plain deterministic logic, not an LLM call — you can read exactly why a54 prospect got the score it did.553. **Personalize** — draft a short outreach email per non-rejected prospect,56 using your own voice examples as a *style* reference only — never copied57 verbatim, never inventing facts about the prospect that aren't in its record.584. **Review (the gate)** — every draft is `pending_review`. You approve, edit,59 skip, or reject each one before it goes anywhere. This is not optional and60 not skippable by config — it's the shape of the tool.615. **Load + Report** — approved drafts get built into the exact payload your62 outreach platform would need; the weekly report shows what moved through63 the pipeline and (once live) what it produced.6465---6667## Why this build never actually sends anything6869Two separate reasons, either one alone would be enough:7071- **This build's own rule.** Real external-send wiring — a live Visual Visitor72 pull, a live Smartlead POST — is a JD-approval matter, not something enabled73 during a build. So `signals/visual_visitor.py` and `load/smartlead.py` ship74 as mock/dry-run-only, on purpose, with a `LiveModeNotImplementedError` that75 fires if you (or an .env file) tries to flip a live-mode flag.76- **An open wiring question.** The product spec for this tool explicitly calls77 for getting Bryan Fikes' field-by-field wiring — his exact Visual Visitor78 plan/API, contact-enrichment setup, and Smartlead campaign structure — in a79 30-minute call *before* writing the real adapters, so the tool packages his80 actual reality instead of a plausible-looking guess. That call hasn't81 happened yet. See `README.md`'s "Live mode" section and the docstrings at82 the top of `signals/visual_visitor.py` and `load/smartlead.py` for the full83 detail, including exactly what's needed before either adapter can go live.8485None of this blocks using the tool today — the whole pipeline (scoring,86drafting, the review queue, the report) is real, tested, and runnable; only87the two outermost edges (pulling real visitor data, pushing a real send) are88intentionally stubbed.8990---9192## What a good result looks like9394- You get a short list of prospects that actually match your ICP, each with a95 plain-English reason they surfaced — not a firehose of everyone who touched96 your site.97- Every draft you see in the review queue reads like something you'd actually98 send, references the real reason the prospect showed up, and never claims a99 stat or fact that isn't in the prospect's record.100- Nothing leaves your review queue without your explicit approve/edit — the101 tool cannot send on your behalf even if you wanted it to, in this build.102- The weekly report tells you honestly what's real (prospects surfaced,103 drafted, approved) vs. what's a placeholder until live sending is wired104 (opens, replies, calls booked all read "n/a — dry-run build" rather than a105 made-up number).106107---108109## How it pairs with the other Founding Circle tools110111- **`bug-hunter`** and this tool share the same "find-and-report first, dry-run112 before any write" posture that `SECURITY.md` requires of anything touching a113 live account or an outbound send.114- **`client-dashboard`** is the natural next step once real sending is live —115 a client-safe weekly view of pipeline/booked-call numbers, never the116 machinery behind them.117- **`connection-monitor`** is worth putting on top of this once it's live: the118 moment a Smartlead or Visual Visitor connection silently drops, you want a119 ping, not a week of an empty pipeline you didn't notice.120121---122123## Where things land124125| File | What it is |126|---|---|127| `SKILL.md` | This walkthrough. |128| `README.md` | Full setup, run commands, and the detailed "why dry-run" explanation. |129| `.env.example` | Copy to `.env` — keys never leave your machine; live-mode flags are refused on purpose in this build. |130| `run.py` | CLI entrypoint (`wizard`, `signals`, `enrich`, `personalize`, `review`, `load`, `report`, `pipeline`). |131| `config/icp.example.yaml` | Copy to `config/icp.yaml`, or build it via `python3 run.py wizard`. |132| `config/voice-examples.example.md` | Copy to `config/voice-examples.md` and paste in 2-3 real emails that got a good reply. |133| `outbound_engine/` | The pipeline code — see `README.md`'s file map for the module-by-module breakdown. |134| `tests/` | pytest, fully offline — run `python -m pytest tests/` from this folder. |