Skip to main content
Glama
fpavia111-creator

Leonidas of the Web

Leonidas of the Web

Formerly leadwright. The npm package is now @kurtfrancisco/leonidas and the command is leonidas; leadwright still works as a deprecated alias.

A compliance-first outbound sales pipeline that runs as an MCP server for Claude Code, Cursor and Codex.

Your coding agent researches leads, scores them against an industry ICP, and drafts cold email. Leonidas checks every draft against CAN-SPAM and deliverability rules, logs why each lead was contacted, and holds everything for a human to approve. By default nothing is ever sent.

Based on Harvey by Ethan Rogers (MIT). Leonidas of the Web is an independent project. It is not affiliated with or endorsed by Ethan Rogers. The skills library and the content rules (banned phrases, merge-tag, link and plain-text checks) come from Harvey. The MCP server, compliance gate, send window, caps, audit log and ICP templates are new.

Why

Autonomous SDR agents fail in the same ways: a fake "Re:" subject, a missing unsubscribe line, a burned domain, an email to someone who already opted out, and no record of why that person was emailed. Leonidas puts deterministic code between the model and the outbox.

Related MCP server: prospector

Features

  • MCP server (stdio, zero dependencies) with 18 tools: leo_add_leads, leo_writer_prompt, leo_check_email, leo_queue_email, leo_why, leo_send_approved, leo_objection, leo_dns_check, and more. The 0.1.x lw_* names still work as aliases.

  • Never auto-sends. sending.mode defaults to "draft". Only a human approves (leonidas approve <id>). Agents can approve only if you set approval.allowAgentApproval: true yourself.

  • CAN-SPAM gate. Every message gets a footer with your physical postal address and an opt-out line. List-Unsubscribe headers are added (one-click when you set a URL). Deceptive Re:/Fwd: subjects on a first touch are blocked.

  • Cold email bodies under 100 words (footer excluded). Hard error at queue and send time. Config can tighten it but can't loosen it.

  • Subject lines under 30 characters. This is a hard error. Config can tighten the limit but can't loosen it.

  • Tuesday/Wednesday sending only. This is a hard rule: sending.allowedDays can narrow it to one of those days but can't add others. It must be Tue/Wed both in the lead's timezone (falling back to sending.timezone) and in America/Chicago. Approved mail that comes up on another day is marked scheduled for the next Tuesday or Wednesday and goes out on the next leonidas send run on or after that date.

  • Built-in SMTP (zero dependencies) for cPanel and other hosted mailboxes: port 465 SSL or 587 STARTTLS, AUTH PLAIN/LOGIN, password from an environment variable only. A 550 on the recipient records a hard bounce and suppresses the address.

  • Verified-only sending by default: leads must be marked emailVerified: true (or verification: "valid").

  • Deliverability. Daily cap, per-domain cap, a warmup ramp (5/day, +3/day, or an explicit sending.ramp), a send window, a minimum gap between sends, quiet hours, a bounce-rate circuit breaker (pauses above 5% hard bounces), and SPF/DMARC/DKIM checks.

  • Do-not-contact list. Blocks exact emails (case and +tag normalized) and whole domains. Hard bounces and complaints are added automatically, and adding an entry pulls any pending mail to that address.

  • Audit log of decisions. Each step records who acted and why, the evidence and the score reasons. The log is append-only JSONL with a SHA-256 hash chain, so tampering shows up. leonidas why <email> shows the full trail.

  • Eight industry ICP templates: SaaS, agencies, home services, dental/clinics, e-commerce, real estate, professional services and manufacturing. Each lead is scored with readable reasons.

  • Content gate from Harvey: banned spam and AI-tell phrases, unrendered merge tags, a one-link budget, plain text only, and a word ceiling. Also blocks role addresses and header injection.

  • CSV import and export. Exports are protected against formula injection.

Quick start

npx -y @kurtfrancisco/leonidas init --icp home_services
# edit .leonidas/config.json (or use YAML: .leonidas/config.yaml, see examples/): sender.name/company/email/physicalAddress, compliance.unsubscribe
npx -y @kurtfrancisco/leonidas install-snippets   # prints configs for all three hosts

Claude Code: claude mcp add leonidas -- npx -y @kurtfrancisco/leonidas mcp Cursor (.cursor/mcp.json): {"mcpServers":{"leonidas":{"command":"npx","args":["-y","@kurtfrancisco/leonidas","mcp"]}}} Codex (~/.codex/config.toml):

[mcp_servers.leonidas]
command = "npx"
args = ["-y", "@kurtfrancisco/leonidas", "mcp"]

Then ask your agent, for example: "Find 20 HVAC companies in Austin, add them to Leonidas, and draft first-touch emails for the qualified ones."

Review and send:

leonidas outbox pending_approval
leonidas show <id>
leonidas approve <id> "looks right"
leonidas send          # only works with sending.mode="send"; only Tue/Wed
leonidas why owner@example.com

Configuration (.leonidas/config.json or config.yaml)

The config is found at $LEONIDAS_CONFIG, else .leonidas/config.yaml, config.yml or config.json. An existing .leadwright/ folder and the LEADWRIGHT_* environment variables from 0.1.x keep working.

Key

Default

Meaning

sending.mode

"draft"

Must be set to "send" explicitly before anything is delivered

sending.allowedDays

["Tue","Wed"]

Weekdays when cold email may go out

sending.timezone

"America/Chicago"

Used when a lead has no timezone

sending.dailyCap / perDomainDailyCap

30 / 3

Hard caps per day

sending.warmup

5/day +3/day

Ramp for a new mailbox

sending.maxBounceRate

0.05

Hard-bounce rate that pauses sending (after 20 sends)

sending.transport

"file"

file writes .eml files to .leonidas/sent/. command pipes the message to e.g. msmtp -t. smtp uses the built-in client (below)

sending.ramp

[]

Explicit warmup caps per day, e.g. [5, 10, 20], then dailyCap. Replaces the +3/day formula. Counted from sending.warmup.startDate

sending.window

none

{start: "09:00", end: "13:00"} in sending.timezone. Mail is held outside it

sending.minIntervalSeconds

0

Minimum gap between two sends

sending.sendUnverified

false

Hold mail to leads not marked verified

sending.personalizeFirstEmail

true

The writer brief requires a business-specific first line

usage.quietHours

none

{start: "22:00", end: "07:00", timezone}. No sending in this window (it may wrap midnight)

usage.maxDailyBrainPercent

100

Budget hint shown in status for the host agent. Not measured or enforced by Leonidas

product.keyBenefits

[]

List of benefits. The writer brief offers the 3 most relevant to each lead and asks for at most one

product.objectionResponses

{}

Map of objection to answer. leo_objection returns the closest match

product.pricing, offer.primary, offer.entry

""

Given to the writer as the only prices it may quote

offer.bookingMethod

"reply"

reply, link (needs offer.bookingUrl) or ask_preference (no link; ask email, text or a short call)

offer.meetingDurationMinutes

15

Number of minutes (import-harvey turns "10 minutes" into 10)

approval.allowAgentApproval

false

Lets the MCP agent approve its own drafts. Leave this off

compliance.maxBodyWords

99

Can only go lower. Bodies must be under 100 words, excluding the footer

compliance.maxSubjectLength

29

Can only go lower. Subjects must be under 30 characters

icp.template

""

One of the 8 templates (leonidas templates)

SMTP for cPanel mailboxes

In cPanel go to Email Accounts > Connect Devices and copy the "Secure SSL/TLS Settings" (outgoing server, usually mail.yourdomain.com).

sending:
  mode: send            # only when you are ready
  transport: smtp
  smtp:
    host: mail.yourdomain.com
    port: 465           # 465 = SSL/TLS. Or 587 = STARTTLS (required; Leonidas refuses to log in unencrypted)
    user: you@yourdomain.com     # the full mailbox address
    passwordEnv: LEONIDAS_SMTP_PASSWORD
export LEONIDAS_SMTP_PASSWORD='mailbox password'   # never put it in the config file; config check rejects it
leonidas config check

secure defaults to true on 465 and false (STARTTLS) on 587. The certificate is verified. If your host's certificate only covers its server name (e.g. server123.hostingcompany.com), use that name as host. caFile points at a custom CA, and rejectUnauthorized: false turns verification off (not recommended). Also set SPF, DKIM and DMARC for the domain (leonidas dns yourdomain.com default). Every gate still runs before a connection is opened: approval, Tue/Wed, subject and word limits, footer, ramp and caps, window, quiet hours, verified-only and the bounce breaker. A 5xx on RCPT marks the message failed, records a hard bounce and suppresses the address. A 4xx leaves it approved for the next run.

YAML configs, Harvey import and validation

leonidas import-harvey harvey.yaml .leonidas/config.yaml   # convert a Harvey-style config (persona/product/offer/icp/channels/usage/brain)
leonidas config check [file]                               # schema and safety check; exit code 1 on errors

import-harvey maps snake_case Harvey fields onto this schema and prints a note for each change. For example, meeting_duration: 10 minutes becomes meetingDurationMinutes: 10, company_size: 1-20 employees becomes "1-20", and provider: smtp becomes transport: smtp. Duplicate YAML keys are reported (the last value wins). Imported configs always start in draft mode. config check warns about risky values: send days other than Tue/Wed, sendUnverified: true, approval turned off, plaintext SMTP. See examples/local-web-agency.yaml for a full example with placeholders.

Pro ($11 launch price)

Leonidas Pro adds:

  • Sequence and playbook packs for 8 industries

  • A deeper compliance and deliverability checker: CASL/GDPR/PECR region rules, list hygiene, spam scoring, a full DNS audit and pack validation

  • A one-command installer that registers the server with Claude Code, Cursor and Codex

Pro is sold separately. The core in this repo is MIT and fully usable without it. Existing leadwright Pro keys keep working.

Buy Leonidas Pro: $11 one-time →

Leonidas helps you follow the rules, but it isn't legal advice. You're responsible for complying with CAN-SPAM, CASL, GDPR/PECR and your mail provider's terms.

License

MIT. Copyright (c) 2026 Ethan Rogers (original Harvey) and Copyright (c) 2026 Kurt Francisco (modifications). See LICENSE.

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables personalized cold email outreach through research, drafting, template management, and deliverability checks, all locally with no required API keys.
    6
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables AI assistants to run a GTM lead pipeline that scrapes sources, applies ICP gates to disqualify leads, checks email deliverability, and requires human approval before any lead is marked qualified.
    3 npm
    1
    Apache 2.0
  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables AI agents to discover companies showing buying signals, enrich them with public homepage data, score them against custom rules, and draft review-ready briefs.
    1
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables agents to find leads, read buying signals, write and send email and LinkedIn outreach, handle replies, and report results, with built-in safety gates, approvals, limits, and compliance controls.
    5
    Apache 2.0