Harvey, the sales agent that runs on your Claude subscription
Autonomous AI sales agent powered by Claude Code or Codex. Finds prospects, writes cold emails, sends campaigns, handles replies, books meetings. No API keys needed — runs on your Claude or Codex subscriptions.
At a glance
- What is it?
- Harvey is a Python sales agent that finds local businesses, reads their sites, and drafts cold email, using a Claude or ChatGPT subscription instead of a per-token API bill. It decides what to do by counting, and it never sends without you.
- Who is it for?
- Adopt Harvey if you sell to small local businesses and already pay for Claude Pro/Max or a ChatGPT plan, and give it a dedicated secondary domain. Skip it if you need verified contact records for larger accounts, per-token cost control, or unattended sending.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository received new commits within the last day.
- 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 24, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Harvey charges your Claude or Codex plan instead of an API bill
Harvey targets a narrow buyer: founders and small sales teams who sell to local businesses, typically firms with five to fifty people. It looks for businesses worth selling to, learns something specific about each one from its website, writes cold email that references that detail, sends campaigns, reads the replies, and works the conversation toward a meeting. The unusual part is the cost model. Harvey drives the Claude Code CLI or an isolated codex app-server, in both cases with the provider's model tools disabled, so every model call is covered by a Claude Pro or Max subscription or a ChatGPT plan with Codex access. The cost table the project publishes is blunt. Finding businesses is $0 on the default source, or roughly $0.37 per 1,000 on the cheapest paid one. Reading their sites is $0, because it makes three HTTP requests per site with no model call involved. Writing and sending needs your subscription plus a mailbox, about $7 a month for Google Workspace. Prospecting tools are listed as none: no Apollo, no ZoomInfo, no Clearbit, no Clay. If you need verified contact records for larger accounts, this is the wrong shape of tool, and the README does not describe a contact database behind it.
A heartbeat that chooses work by counting, not by asking a model
Harvey runs a heartbeat rather than a chat. It wakes up, checks quiet hours, checks the budget, decides what most needs doing, does it, logs it, and sleeps, every fifteen minutes by default. The decision is deterministic, and the priority order is fixed:
handle replies > send campaigns > write campaigns > prospect > idle (analyze)The reasoning behind that ordering is stated plainly: deciding this way avoids spending a model call on something already derivable from four counts. Profiling and outbox draining run on every cycle regardless of the decision, because the project treats them as free and time-sensitive. A real cycle looks like this:
$ harvey run
============================================================
Harvey is online. Always Be Closing.
============================================================
Checking pipeline state...
Decision: prospect (only 3 new prospects; pipeline needs leads)
discover → 41 businesses in Portland, OR ($0.00, OpenStreetMap)
profile → 41 sites read, 288 observations (free, no model calls)
scout → 12 scored against your ICP
Decision: write_campaign (12 new prospects with no drafts)
writer → 3-email sequence for Cascade Landscaping
outbox → 12 emails waiting for your approval
Cycle complete. Sleeping for 15 minutes.Note what that output does not contain: a token count, a latency figure, a cost per email. The only prices shown are on the discovery step, at $0.00 for the default source. That is the shape of the whole design, and it is also the thing to watch. Every personalised sentence and every reply classification is charged to your own plan, invisibly.
Quick start: two routes to a running agent
The project ships a setup path built around Claude Code itself. The README opens the install with a clone and a CLI:
git clone https://github.com/ethanplusai/harvey.git
cd harvey
claudeThen you ask Claude Code to set up Harvey for you. The repository contains a CLAUDE.md file that turns the CLI into a wizard: it inspects your state, installs what is missing, asks for what it needs, and trains the agent on your product. Doing it by hand takes six commands:
python3.13 -m venv .venv && source .venv/bin/activate && pip install -e .
cp .env.example .env && $EDITOR .env
harvey train https://your-company.com
harvey signals --confirm free
harvey discover
harvey dashboard # http://localhost:5555
harvey runTwo prerequisites trip people up. Python 3.11 or newer is required, and macOS ships 3.9, so the venv has to be built with python3.13 or the agent will not run. The provider CLI must already be logged in, and mail should go out from a dedicated secondary domain, since Microsoft 365 is also supported and documented separately. After the manual route, the dashboard serves at localhost:5555 and the heartbeat starts with harvey run.
Signals, cohorts, and the cost of a discovery run
The step the project insists you do not skip is signal selection, and it is the step that decides whether the rest is worth running. You tell Harvey what a good prospect looks for, and you confirm it with the confirm flag, which is why the quick start runs harvey signals --confirm free. Every other source of leads is downstream of that choice. The dashboard carries a queue for the current day, a panel to confirm a signal, a cohort builder that counts matches as you type, and a costed estimate for a discovery run before anything is spent. The repository layout backs this up: a harvey.yaml config file, a prompts directory, a skills directory, and an .env.example whose variables are documented inline with where to get them. Cost control is partly the same mechanism. Harvey reads the active provider's subscription quota and throttles to leave headroom for your own use of Claude or Codex, and the setting is called max_daily_claude_percent, with a note that the name predates Codex support. If the quota cannot be read at all, Harvey reports it as unavailable and falls back to its own daily call budget, which means you lose visibility rather than losing control.
Twelve drafts sit in the outbox until you approve them
Sending is the part Harvey refuses to do on its own. The cycle output above ends with twelve emails waiting for your approval, and the dashboard is described as an outbox decisions desk where you approve mail one message at a time. So the loop in practice is: discover, profile, score, write a three-email sequence, park it for review, send only what you accept, then read the replies and work them toward a meeting. Two consequences follow. The agent is fast at the cheap, repeatable work and slow at the part that actually needs judgment, which for a cold email is the right place to spend a human. And the review step is linear, one message at a time, so a large campaign still needs a large number of decisions. The documentation also lists a legal and deliverability section in its table of contents, alongside a troubleshooting section, and the repository points to a separate Microsoft 365 setup document. Cold email at this volume is a deliverability question as much as a copy question, and the sample cycle gives no view into inbox placement, bounce handling, or how many of those twelve drafts would have landed in spam.
Docker runs it as a non-root user with your Claude login mounted
For a long-running agent, the compose file is the more honest deployment. It builds from the local Dockerfile, loads .env, and mounts the state, config, prompts, skills and, importantly, your Claude authentication directory:
services:
harvey:
build: .
env_file: .env
volumes:
# Persist database across restarts
- ./data:/app/data
# Mount config for easy editing without rebuild
- ./harvey.yaml:/app/harvey.yaml:ro
- ./prompts:/app/prompts:ro
- ./skills:/app/skills
# Mount Claude auth (required for Max plan usage).
# Not read-only: the CLI refreshes OAuth tokens in place.
# The container runs as non-root user "harvey" (uid 1000).
- ~/.claude:/home/harvey/.claude
restart: unless-stoppedThe Dockerfile starts from python:3.12-slim, installs Chromium through Playwright for site reading, creates a non-root user harvey with uid 1000, and installs the Claude CLI as that runtime user. Its health check is simple and worth copying: the service is healthy when the database file has been touched within a two-hour window, which tolerates both long heartbeat intervals and quiet-hour idling. The compose comment about ~/.claude is the detail to notice. That mount is deliberately writable because the CLI refreshes OAuth tokens in place, which means a container with your subscription credentials mounted is a container with your subscription credentials in it.
A beta project with two releases on the same day
The packaging is honest about its stage. The version is 0.3.0, the development status is classified as Beta, and the licence is MIT. Two releases landed on 2026-10-13: v0.2.1, labelled a security release, and v0.3.0, the release that brought the Claude or Codex subscription framing. The last push was on 2026-10-15. That is a young project moving quickly, which cuts both ways. It moves fast enough to still be changing its provider support, as the stale max_daily_claude_percent name shows, and it is young enough that the published cost table and the sample cycle output are the only evidence of how it behaves. Two limits deserve naming. The per-request model tools are disabled in both provider modes, so Harvey owns prospecting and mail handling itself rather than letting the model call external tools. And the value proposition rests on your subscription's usage limits rather than on a bill, which means a busy month of agent work shows up as quota pressure on your own coding sessions, not as a line item you can forecast.
Editorial conclusion
Adopt Harvey if you sell to small local businesses and already pay for Claude Pro/Max or a ChatGPT plan, and give it a dedicated secondary domain. Skip it if you need verified contact records for larger accounts, per-token cost control, or unattended sending. Before the first run, check the usage limits of the plan you point it at, because Harvey throttles against that quota rather than a bill you can inspect, and set max_daily_claude_percent to leave room for your own work.
Frequently asked questions
Does Harvey need an API key to run?
No. Harvey uses the Claude Code CLI or an isolated codex app-server with model tools disabled, so model calls are covered by a Claude Pro or Max subscription or a ChatGPT plan with Codex access rather than a per-token API account.
What does it cost to run Harvey?
The published figures are $0 for finding businesses on the default source or about $0.37 per 1,000 on the cheapest paid source, $0 for reading their websites, and your subscription plus a mailbox (around $7 a month for Google Workspace) for sending.
Will Harvey send cold email without my approval?
No. Drafts are parked in an outbox, and the project states plainly that nothing sends without you, with messages approved one at a time in the dashboard that runs at localhost:5555.
How do I run Harvey in Docker?
The repository ships a Dockerfile based on python:3.12-slim and a docker-compose.yml that mounts ./data, harvey.yaml, prompts, skills and your ~/.claude directory, which must stay writable because the CLI refreshes OAuth tokens in place.
Is Harvey actively maintained?
The last push was on 2026-10-15, and two releases landed on 2026-10-13, v0.2.1 as a security release and v0.3.0. The current version is 0.3.0 with the development status classified as Beta.
Official sources
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.
[](https://hysenlabs.com/projects/ethanplusai-harvey)Was this useful?