agentsclimarketplace

Cold email drafter

Skill AirDoogle/claude-skills/skills/cold-email-drafter

Curated Claude Code agent skills — local business lead prospecting and cold-email outreach (bring your own API keys).

Install
npx -y skills add AirDoogle/claude-skills --skill cold-email-drafter

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

2 things to look at

  • 21 days oldThe repository was created 21 days ago. New is not bad, but a brand new repository carrying a familiar-sounding name is the shape a typosquat arrives in, and there has been no time for anyone else to find a problem with it.
  • 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

Draft a short, human cold email for a prospect in the Notion Prospecting Clients table with ZERO LLM tokens. One editable template fills from the row's columns (Website Status gap, add-on, sector, area, name). Two no-flag paths: click the row's Draft Email link to open a pre-filled Gmail, or invoke by name to save it straight to Gmail drafts. Pairs with local-lead-prospector.

The file declares its own license as private. That is the author’s claim about this one file, and it is not the same thing as the license GitHub reports for the repository, which is listed with the other numbers below.

SKILL.md

7.0 KB, ~1.7k tokens by cl100k_base, as published. Nobody here has run it

DM 2 — Outreach (cold-email drafting)

Turns a scored lead from DM_1 into a send-ready cold email without spending a single model token. All wording lives in one plain-text template; a Python script pulls the chosen business's Notion row and fills the blanks. The model's only job is to run the command and hand you the output.

The offer mirrors DM_1: the core pitch is a website, keyed to the specific gap in Website Status; booking / chatbot / automation / analytics are add-ons, mentioned only when the row has that flag.


How to use it — two ways, no flags to type

1. Press it in Notion (fastest). Every lead that has an email has a Draft Email link in its row. Click it and Gmail opens with the subject and body already filled in from the template. Read it, send it. Nothing to install, no command to run.

  • These links are generated by refresh_draft_links.py (below). Re-run that after a prospecting run or after you edit the template.

2. Ask Claude by name. Say /cold-email-drafter Example Business (or "draft the email for Example Business"). Claude drafts it fresh from the current template and saves it straight to your Gmail drafts, then opens the drafts folder. You just name the business — Claude runs the script for you.

Behind the scenes Claude runs:

python3 draft_email.py "Business Name" --gmail-draft

You never type that. --gmail-draft creates the Gmail draft (never sends) and opens https://mail.google.com/mail/u/0/#drafts; the new draft is at the top. Add --open-stitch (or just ask) to also open Stitch for a mock-up. Without --gmail-draft the script only prints the email for copy-paste.

If several businesses match the name, it takes an exact case-insensitive match, else the first, and says which on stderr.

Keep the Notion "Draft Email" links current

python3 refresh_draft_links.py

Fills the Draft Email column with a one-click Gmail compose link for every lead that has an email, using the current template. Run it after a DM_1 prospecting run, and again whenever you edit email_template.txt (the links bake in the wording, so refresh to update them). No flags, zero tokens.

Prototype in Stitch

There is no URL that spins up a fresh Stitch project on its own — Stitch is behind a Google sign-in and only creates a project from its in-app button. Open Stitch (from the button on the Notion page, or --open-stitch), click Create new project, build the mock-up, then paste the project URL into that lead's Stitch Link column by hand.

Gmail auth

Both Gmail paths use the OAuth credentials in ~/.gmail-mcp/ (set up by the Gmail MCP) and talk to the Gmail API directly with curl — the MCP itself does not need to be connected. If the token can't refresh, the script falls back to printing the email so you can copy-paste. u/0 is the default account; change it in the scripts if the wrong account opens.


The files

FileRoleWho edits it
email_template.txtThe ONE template: subject, body, sign-off, and the token key.You (freely)
draft_email.pyReads a row, fills the template, prints it, and (with --gmail-draft) saves a Gmail draft.rarely
refresh_draft_links.pyRebuilds the Notion Draft Email click-to-compose links from the current template.rarely

One edit, every future draft

email_template.txt is the single source of truth for wording. Change a sentence, the call-to-action, or the sign-off there and every draft generated after that uses the new text — nothing is cached, the file is re-read on every run. No code change, no redeploy, no touching the script. That is the point of keeping the copy in a template file instead of inside the Python.

Two wording maps live in draft_email.py (not the template) because they are keyed tables, not free prose:

  • STATUS_PITCH — the Website Status → gap-pitch lines. These make the same point as DM_1's "Website Status → pitch" table, phrased for email (the email version is a full sentence, DM_1's is a short line you say on a call). If you change the gap you lead with in one, change it in the other so the call and the email agree.
  • ADDON_LINE — the one soft sentence per Add-on Flag.

Editing those is still a one-place change; they're just in the script because each is a lookup table rather than a paragraph.


Token → column map (what the script fills)

TokenNotion columnFallback when blank
{business_name}Business Name (title)"your business"
{first_name}Decision-maker Name (first word)"there"
{sector_plural}Sector (mapped to a natural phrase)"local businesses"
{area}Area"your area"
{website_status_pitch}Website Status → STATUS_PITCHgeneric web-value line
{addon_line}first Add-on Flag → ADDON_LINE"" (line closes up)
{sender_name}--sender / SENDER_NAME in script"Your Name"
{sender_line}--sig / SENDER_LINE in script"" (line drops)

Fallback behaviour:

  • Unknown token (typo in the template) is left visible as {like_this} so you catch it in the draft rather than shipping a hole.
  • A token that resolves to empty (e.g. no add-on flag) collapses its blank line — no dangling spaces or double blank lines.
  • Modern-skip / unknown Website Status → the generic pitch, so the email still sends.

Writing rules baked into the copy (keep them)

The template is deliberately written to not read like AI:

  • 4–6 lines, one specific gap, one optional add-on, one soft CTA.
  • No em-dashes, no "I hope this finds you well", no rule-of-three lists.
  • Plain natural language; contractions; a real question at the end.
  • The STATUS_PITCH and ADDON_LINE strings follow the same rules — if you edit them, keep them dash-free and conversational. Run the humanizer skill over any new wording.

Notion connection

Same table, token and DB ID as DM_1 (local-lead-prospector). Node is EPERM-blocked in the Apple sandbox, so this is pure Python + curl. Read-only: DM_2 never writes to Notion — it only fetches the row to draft from. Update Status / Last Contacted by hand (or via DM_1's helpers) after you send.


What not to do

  • Don't draft emails token-by-token with the model — that's the whole thing this avoids.
  • Don't scatter copy across the script; wording belongs in email_template.txt.
  • Don't let STATUS_PITCH drift from DM_1's pitch table — the call and email must agree.
  • Don't add a second template file; one editable template, one place.

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.