Model or dataset
eracle/OpenOutreach avatar
eracle/OpenOutreach

OpenOutreach: a self-hosted AI agent that finds B2B leads and emails them

Open-source AI agent for B2B lead generation — describe your product, it finds the people who fit, explains why each one does, and emails them from your mailbox. Self-hosted CLI, one install.

3,120 stars572 forksPythonGPL-3.0

At a glance

What is it?
OpenOutreach turns a product description into qualified leads with a written reason for each one, then sends from your own mailbox. It is a Python CLI that orchestrates two separate programs, and it buys work addresses with credits.
Who is it for?
Adopt OpenOutreach if you are a developer or technical founder who wants the find-then-send loop on your own machine, is comfortable with a Python 3.11+ tool install, and treats the first run as a paid experiment at five credits. Do not adopt it if you need a hosted dashboard, a team seat model, or a tool that scrapes LinkedIn, because the README states it is browserless and has no social-network account.
Can I use it commercially?
Yes, with conditions. GPL-3.0 is a copyleft licence: if you distribute software that includes it, you must release that software's source code under the same licence. Running it internally without distributing it does not trigger that obligation.
Is it still maintained?
Yes. The repository last received commits 2 days ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 1, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The list-building step OpenOutreach removes

Most outreach tooling assumes you already have names. A sequencer wants a CSV of prospects; a lead database wants you to filter rows until something looks right. OpenOutreach inverts that. The README states the input is a sentence about your product, and the output is a verdict per person rather than rows. You describe the product and the target market, and the agent discovers matching people from a licensed data provider, judges each against the ICP it derived from your description, and writes out why each person was chosen. Then it opens the conversation from your own mailbox.

The audience is narrow and technical. The install path is uv tool install, the configuration lives in ~/.openoutreach, and the interface is a CLI with verbs. A sales team that wants a web dashboard and shared seats is not the target. A developer or a technical founder who would rather read a CSV on stdout and pipe it somewhere is.

Two child programs behind one command

OpenOutreach is an orchestrator, not a monolith. The README describes three packages: OpenOutFind handles discovery, qualification, enrichment and the CRM; OpenOutSend handles the outreach agent, the mailbox and the send guards; the openoutreach package installs both and hosts them in one process, one database and one onboarding.

The contract between the children is deliberately public. The README gives this pipe as the boundary:

bash
outfind find 50 --json | outsend      # anybody's producer, anybody's receiver
outsend send                          # a separate invocation, on the mailbox's clock

When you run openoutreach run, the same JSON Lines cross the same boundary, just inside a buffer. The README is explicit about why there is no privileged in-memory hand-off: a second, untested path between the same two programs would make the public one a lie. That is an unusual design argument to find stated outright, and it means the bundled command is not a different code path from the pipe, only a different invocation of it.

The wizard exists in this package because the children do not have one. Both are agent-first: they read configuration from OPENOUTFIND_* and OUTSEND_* environment variables on every run and remember none of it. That suits a script or an agent and does not suit a person, so the questions are asked here, stored here, and handed to each child in its own variables.

Installing OpenOutreach and running your first five leads

The README gives a two-line install. The first line installs the CLI as a uv tool, the second runs it. A bare invocation onboards you if it has to, finds leads that fit, buys a verified work address for each, and emails them from your mailbox.

bash
uv tool install openoutreach
openoutreach

If you want to control the size of the first run, the README shows the run verb with a count. The comment in the README states this finds five leads carrying an address and then sends, at most five credits.

bash
openoutreach run 5        # find five leads carrying an address, then send — at most 5 credits

Before spending anything, onboard without sending. The README describes init as one flow, every answer, nothing spent.

bash
openoutreach init

The two long fields can come from files instead of being typed into the wizard, which is the practical path if your product description already exists as a document.

bash
openoutreach init --product-docs product.md --target target.md

Then run a free find to see the shape of the output. The README states that find without the emails unit is free and cannot spend, and that find 0 prints what you already have without doing work.

bash
openoutreach find 10 > leads.csv
openoutreach find 0

The CSV columns are fixed and the README lists them: email, first_name, last_name, company, title, website, linkedin_url, reason, lead_id, qualified_at. The reason column is the part worth reading first. If the verdicts look wrong, you correct the product description, not the rows. Adding emails to the unit costs one credit per address, as in openoutreach find 10 emails.

State, credits and the cost of not finishing a run

Everything lives in ~/.openoutreach. The README states that stopping and starting loses nothing, because the number you ask for is more than you already have, so running the command again continues where it left off. That is a sensible model for a CLI that spends money per address: an interrupted run is not wasted work, it is a smaller run.

The credits are the real constraint. Discovery and qualification are free in the find path; buying a verified work address costs one credit each. The README does not document a credit price, a refund path, or what happens to a credit if an address turns out to be undeliverable. Those are the questions to answer before pointing the tool at a large number. The run verb caps the spend at the count you pass, which is the only budget control the README describes.

There is also a legal step in the flow. The README states the Claude Code skill never accepts the legal notice for you, which implies the notice is something a human accepts. LEGAL_NOTICE.md and PRIVACY_NOTICE.md sit at the top level of the repository, and they are the files to read before the first send.

The Claude Code plugin and what it will not do

The repository ships a Claude Code plugin. The README gives the two commands:

code
/plugin marketplace add eracle/OpenOutreach
/plugin install openoutreach@openoutreach

The skill lives at skills/find-leads/SKILL.md and teaches Claude when to run find, which flags cost credits and which cannot, how to read the CSV on stdout, and what each error: <type> means. The README states three boundaries the skill holds: it never buys an address you did not ask for, never sends without being asked, and never accepts the legal notice for you. If you would rather not install a plugin, copying skills/find-leads/ into ~/.claude/skills/ is the documented alternative.

The skill is not Claude-specific despite the packaging. The README describes it as a markdown file describing the CLI's own contract, and says Codex, Cursor or any other agent can call the same find, send, run and status commands by pointing its instructions file at skills/find-leads/SKILL.md. In practice that means the plugin is a convenience wrapper around rules you could paste into any agent's context.

Where OpenOutreach is the wrong tool

The README states the project has zero platform-ToS surface: it is browserless, uses no social-network account, and does not scrape. That is a deliberate boundary, and it rules things out. If your strategy is LinkedIn connection requests and InMail, this tool does not do it, and the related searches asking about LinkedIn outreach tools are asking about a category OpenOutreach has chosen not to enter. The linkedin_url column in the CSV is a data field, not a channel.

The second limitation is the interface. There is no web UI described in the README, no team accounts, and no scheduling beyond the mailbox's own clock, which the README names as the timing for a separate outsend send invocation. Someone who wants to hand a campaign to a non-technical colleague will not get far.

The third is maturity. pyproject.toml declares Development Status :: 4 - Beta, and the version field is 0.1.0 with the comment that the patch number is derived at publish time from the commit count since v0.1.0. The README also states that every green push to main releases, so the published version moves often. A team that needs a frozen, audited release line should look at that publishing model carefully before depending on it. The last push to the repository was on 2026-09-07.

OpenOutreach against a sequencer or a lead database

The honest comparison is with the two categories the README itself names. A cold-email sequencer such as the ones built around uploaded CSVs assumes you bring a list; OpenOutreach has nothing to upload, and the input is a sentence about your product. A lead database returns rows you filter yourself; OpenOutreach returns a verdict per person in plain language, and the README frames correcting the description as the way to correct the verdicts. That difference matters most in the first week, when your ICP is still a guess.

For teams that already have a working list and a working sender, the bundle is the wrong shape. The README points those users at the two standalone CLIs and the JSON Lines pipe instead: uvx --from openoutfind outfind find 10 for the finder, uvx --from openoutsend outsend send for the sender. Each child keeps its own console script, settings module and test suite, so adopting one does not drag in the other. If you already run an outbound stack you like, replacing only the discovery half is a legitimate way to use this project.

Licence and the cost of running your own copy

The licence is GPL-3.0-or-later, declared in pyproject.toml as license = "GPL-3.0-or-later" with license-files = ["LICENCE.md"]. That is a copyleft licence, and it matters if you plan to modify OpenOutreach and distribute the result or offer it as a hosted service. The repository also carries LEGAL_NOTICE.md and PRIVACY_NOTICE.md at the top level, which is a signal that the data sourcing has terms attached. This is not legal advice; read those files and the GPL text before you build on it commercially.

Upgrade cost is low by design. The install is a uv tool, the state is a directory under ~/.openoutreach, and there is no container or daemon manager in the user-facing path. The Makefile's Docker targets are marked as the server deploy only, and the comment points at docs/infrastructure.md §7, so the container path is not the normal one. The real upgrade risk is the publishing model: because every green push to main releases and PyPI version numbers are single-use, an unpinned install can move under you. Pinning the version in your own environment is the obvious mitigation, and the README does not say the project offers a stable channel.

Editorial conclusion

Adopt OpenOutreach if you are a developer or technical founder who wants the find-then-send loop on your own machine, is comfortable with a Python 3.11+ tool install, and treats the first run as a paid experiment at five credits. Do not adopt it if you need a hosted dashboard, a team seat model, or a tool that scrapes LinkedIn, because the README states it is browserless and has no social-network account. Before spending anything, run openoutreach init and openoutreach find 0 to read the free CSV, and check LEGAL_NOTICE.md and PRIVACY_NOTICE.md for how the licensed data provider is used.

Frequently asked questions

What is the best LinkedIn outreach tool?

OpenOutreach is not one. The README states it is browserless, uses no social-network account and does no scraping, so it has zero platform-ToS surface. It finds people from a licensed data provider and emails them from your own mailbox instead.

Is there an AI agent that can automate LinkedIn messages?

OpenOutreach automates outreach but not through LinkedIn. The README describes an agent that qualifies leads and sends email from your mailbox, and it lists linkedin_url only as a CSV column. Messaging inside LinkedIn is outside what the project documents.

What is outreach on LinkedIn?

The README does not define LinkedIn outreach, and OpenOutreach does not perform it. The project's own scope is B2B lead discovery plus email sent from your own mailbox, with no social-network account involved.

Official sources

  1. eracle/OpenOutreach on GitHub
  2. Issues
  3. License: GPL-3.0
  4. Project website
  5. README
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/eracle-openoutreach.svg)](https://hysenlabs.com/projects/eracle-openoutreach)