seed-closer
Skill51 starsChanged 11 days agoMITView on GitHub
The Closer. Sends personalised outreach emails to investors, manages the conversations and keeps following up until an investor call is booked, and nothing leaves the user's inbox without their yes. Drafts one RFC 5322 .eml per investor from seed/investors.json and a template (a real personal line, the sender's real name and an opt-out line, generic lines refused), shows the batch, records the user's yes word for word, enforces a daily cap of 20, then Claude sends through the user's own Gmail connector where the Allow once card is a second check. Schedules follow-ups on +3 and +7 business days (3 touches at most, never after a reply), sorts replies into interested / question / not now / no / out of office, stops a thread for good on a no, an opt-out or a bounce, writes a valid .ics invite and shows the funnel. Reads seed/config.json and seed/investors.json, writes seed/pipeline.json, seed/outreach/ and seed/calls/. Use when the user says "email the investors", "send the outreach", "follow up with everyone who hasn't replied", "who do I follow up with today", "sort my replies", "book the call", "send her an invite", "how is the raise going", or after /seed-investors ranks the list.
1 other project uses a version of this.
Adopted by
Most recently taken up by
- neubauerwilli/seed-skilltheir own version, first seen Nov 8, 2026
Other versions1 project uses a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 1
- neubauerwilli/seed-skill★ 2same name
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository10 other files it gives its agents.
- seed-coachSkill
- seed-dataroomSkill
- seed-deckSkill
- seed-investorsSkill
- seed-marketSkill
- seed-modelSkill
- seed-planSkill
- seed-scoutSkill
- seed-termsSkill
- seed-updatesSkill
The file
Show its rules and text
We split this skill into the rules it gives an agent
14 rules. About 0 are common, 7 are distinctive, and 7 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈7
Distinctive · estimate
This author's own choices. Worth a look.
7
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 50
Every command takes --dir (default ./seed) and --today YYYY-MM-DD (pin the date).
- Very specific: line 117
Only after "Recorded your yes", send each email from the JSON it printed, one tool call per email: send_message with that to, subject and …
- Very specific: line 122
After each send: closer.py log --id <id> --event sent --thread-id <id from Gmail>.
- Very specific: line 125
Never from a scheduled or background task.
- Very specific: line 130
Check seed/config.json: the user's real name, the address they send from, a postal address (anti-spam laws such as CAN-SPAM expect one).
- Distinctive: line 137
Run the Gmail loop above for the batch: batch, the yes, send, log.
- Very specific: line 138
Every business day: closer.py due.
- Very specific: line 141
Read new replies with search_threads / get_thread (read only, for example from:maya@northlight.example newer_than:14d).
- Distinctive: line 183
After the user's "yes", Claude sends the six through Gmail.
- Distinctive: line 206
Never sends, and never lets Claude send, without the user's yes for that batch.
- Distinctive: line 208
Never writes to anyone without a public source in their row, never guesses an email address, never collects a personal phone number or home …
- Distinctive: line 210
Never emails a thread again after a no, an opt-out or a bounce.
- Distinctive: line 211
Never invents a fact in a personal line or a number in a reply.
- Distinctive: line 212
Never promises funding. The pack does the work.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
seed-closer
The Closer does the part of a raise that eats the founder's week: one personal email per investor, the follow-ups nobody remembers to send, the replies sorted, and the call on the calendar. It writes everything; it never sends anything. Claude sends through the user's own Gmail, only after the user said yes to that exact batch in the chat, and Claude's own "Allow once" card asks again for every email. All the user has to do is say yes, show up and pitch. Investors decide; nothing here promises a check.
${CLAUDE_SKILL_DIR} below is this skill's folder (where this SKILL.md lives).
python3 "${CLAUDE_SKILL_DIR}/closer.py" draft --top 20 # one .eml per investor, status drafted
python3 "${CLAUDE_SKILL_DIR}/closer.py" batch # recipients, their personal lines, the first email in full
python3 "${CLAUDE_SKILL_DIR}/closer.py" approve --batch 3f9a1c2e --reply "yes" # the user's reply, word for word
python3 "${CLAUDE_SKILL_DIR}/closer.py" outbox --json # exactly what to send: to, subject, body, thread
python3 "${CLAUDE_SKILL_DIR}/closer.py" log --id maya-chen --event sent --thread-id 18c2f0a1
python3 "${CLAUDE_SKILL_DIR}/closer.py" due --today 2026-10-29 # who gets a follow-up today
python3 "${CLAUDE_SKILL_DIR}/closer.py" followup --due --extra "Here's our 60-second demo: https://..."
python3 "${CLAUDE_SKILL_DIR}/closer.py" inbox --file replies.json # sort replies, then --write
python3 "${CLAUDE_SKILL_DIR}/closer.py" reply --id maya-chen --body-file answer.txt
python3 "${CLAUDE_SKILL_DIR}/closer.py" book --id maya-chen --start "2026-11-05 10:00" --tz America/New_York --link https://meet.google.com/abc-defg-hij
python3 "${CLAUDE_SKILL_DIR}/closer.py" status # the funnelEvery command takes --dir (default ./seed) and --today YYYY-MM-DD (pin
the date). --json on batch, outbox, due, inbox and status.
What it reads and writes
| file | what |
seed/config.json | startup (name, one_liner, optional tagline, raise, stage), founder (your real name, the address you send from, company_address), outreach (daily_cap 20, followup_days [3, 7], max_touches 3, business_days true, optional holidays) |
seed/investors.json | from /seed-investors: id, name, firm, email, sources, fit, reasons, personal_line |
template.txt | the intro and the two follow-ups (this folder; copy it to seed/template.txt to make your own) |
seed/outreach/<id>-<n>.eml | each draft: a valid RFC 5322 message (CRLF, From, To, Subject, Date, Message-ID, plain text); follow-ups carry In-Reply-To |
seed/pipeline.json | one row per investor: status, touches, next_due, labels, notes, the waiting draft, the Gmail thread id, the call, the history |
seed/calls/<id>.ics | the invite: RFC 5545, CRLF, folded at 75 octets, UTC times, UID, SEQUENCE, ORGANIZER, ATTENDEE, the video link |
The rules it enforces
- A real personal line or no email. Each intro needs
personal_line: one sentence about this investor from their public record. Refused: empty, under 7 words, cut off with "...", a placeholder, a stock opener ("hope this finds you well", "big fan", "love what you're doing", "impressive portfolio", "came across your profile"), the same line used for two people, and a line that names nothing from their row (a deal, a post, a sector, a number). Rows without an email or a public source URL are refused too. - Your real name and the opt-out line.
founder.namemust be a real name ("Your Name" is refused). Every intro and follow-up carries "Not a fit? Reply 'no' and I won't follow up." A batch whose .eml lost it is refused. - The yes.
approvetakes the user's reply word for word and the batch idbatchprinted. It counts only a reply that starts with "yes" and has no condition in it: "sure", "ok", "yes but drop Marcus", "yes tomorrow", "yes?" and a count that does not match the batch are not a yes. If the drafts changed after the batch was shown, the id no longer matches and nothing is recorded.log --event sentworks only on an approved email. - The daily cap. 20 cold emails a day by default (intros and follow-ups, counting today's sends and every approved one not sent yet), 50 at most whatever the config says. Replies in a live conversation do not count.
- Three touches. The intro on day 0, follow-up 1 on +3 business days and
follow-up 2 on +7 (weekends and
outreach.holidaysskipped), never sooner than the planned gap after the touch before, and never once they replied. - Stops. A no, an opt-out or a bounce ends the thread for good: the
waiting draft is void, nothing more is recorded, and
draftrefuses that address forever. "Not now" is a soft pass: no more follow-ups, and /seed-updates can keep them posted if they asked. - Out of office is not a reply: the follow-up waits until the business day after the return date it finds ("until Monday, November 9"), and a follow-up already drafted is voided and drafted again then.
Statuses: drafted, approved, sent, replied, interested, booked, and the ends passed, bounced, optout.
Sending: the Gmail-connector loop
The user connects their own Gmail in Claude (Customize > Connectors) and sets
the tools that send or draft to Needs approval, never Always allow. In
Claude Code, keep them on ask in .claude/settings.json and never in allow.
In the Claude Gmail connector checked on 2026-10-26 the tools are
send_message (send), create_draft (leave it in Drafts), reply (answer
inside a thread), search_threads and get_thread (read only); another
Gmail connector may name them differently. Nothing goes out any other way: no
mail-merge tool, no SMTP, no third-party sender.
closer.py batch. Show the user what it prints, as it prints it: every recipient with their personal line, the first email in full, the count against the daily cap. Ask: "Send these N emails from your Gmail? Reply yes or no." One batch per question.closer.py approve --batch <id> --reply "<their reply, word for word>". "Not recorded" means it was not a clear yes: ask again, never turn a reply into a yes yourself. To send fewer, show a smaller batch (--ids,--limit).- Only after "Recorded your yes", send each email from the JSON it printed,
one tool call per email:
send_messagewith that to, subject and body (orcreate_draftif the user would rather press send in Gmail). A follow-up or a reply goes in its thread withreplyand thethread_id. Each call raises Claude's "Allow once / Deny" card: the second check. - After each send:
closer.py log --id <id> --event sent --thread-id <id from Gmail>. Denied on the card:log --id <id> --event denied(back to drafted, it needs a new yes). Stop the loop if anything looks wrong. - Never from a scheduled or background task. A schedule may run
due,followup --dueand read replies; sending always waits for the user.
Steps
- Check
seed/config.json: the user's real name, the address they send from, a postal address (anti-spam laws such as CAN-SPAM expect one). Readseed/investors.jsonfrom /seed-investors; ask before writing to anyone with a personal mailbox. closer.py draft --top 20. Read back what it refused and why. Fix a refused personal line from the investor's sources, never by inventing a fact, then draft that id again.- Run the Gmail loop above for the batch: batch, the yes, send, log.
- Every business day:
closer.py due. For the ones due,followup --due(an optional--extraline for follow-up 1,--askfor the last one), then the same loop. - Read new replies with
search_threads/get_thread(read only, for examplefrom:maya@northlight.example newer_than:14d). Put them in a replies.json ([{"from", "subject", "date", "text"}]) and runinbox. Show the user each label and the suggested next step, theninbox --write. Labelling the threads in Gmail (Interested, Asked a question, Not now) is optional: ask first. - A question: draft the answer from
seed/plan.jsonandseed/model.jsononly (never a number that is not in them),reply --id ... --body-file, then the loop. The .eml carries no attachment: link the deck, or the user attaches the PDF in Gmail. - Interested: find two free slots with the user's calendar (read only, for
example
suggest_timeorlist_events) and offer them in a reply. When they agree on a time,inbox --writethat reply, thencloser.py book. Show the invite, ask "Send this invite to Maya? Reply yes or no", and after the yes create the event in the user's own calendar with the investor as a guest (Google Calendarcreate_eventsends the invite), or attach the .ics to a reply in the thread. closer.py statusfor the funnel. Hand off: /seed-coachagendafor each booked call, /seed-updates--to prospectsfor the soft passes, and /seed-terms and /seed-dataroom when an investor asks for next steps.
Example: the reel
Leashly is fictional, and so are the investors. draft --top 6 --today
2026-10-26 writes six intros from the founder's own address; Maya Chen's
(Northlight Ventures, fit 96) reads:
To: Maya Chen <maya@northlight.example>
Subject: Leashly: dog walks without the surprise fees
Hi Maya,
Saw you led two pet-care seed rounds, so you know the 20% fee problem better than anyone.
Leashly is a dog-walking app with flat prices and a backup walker on every walk.
We're raising a $1.5M seed. Open to a 20-minute call next week?
Not a fit? Reply 'no' and I won't follow up.After the user's "yes", Claude sends the six through Gmail. The reel's 40
emails would go out over two days at the daily cap of 20. With no reply, due
--today 2026-10-29 lists follow-up 1 on Thursday, Oct 29 (+3 business days),
and follow-up 2 would come on Wednesday, Nov 4 (+7 business days; with
business_days: false it is Monday, Nov 2). Maya replied on Oct 30: "What's
your take rate, and how do you guarantee the backup walker?" inbox labels it
Asked a question and the follow-ups stop. Claude answered from the plan ("15%
flat, no owner fee. Every walk is booked with a second walker on standby
within 1 mile.") and asked "Would Thursday at 10 work for 20 minutes?". Her
"Thursday 10am works. Send an invite." is Interested, and
closer.py book --id maya-chen --start "2026-11-05 10:00" --tz America/New_York --link https://meet.google.com/abc-defg-hijwrites seed/calls/maya-chen.ics: "Leashly × Northlight Ventures · Intro
call", DTSTART 20261105T150000Z, DTEND 20261105T153000Z (10:00 to 10:30 AM
Eastern; the clocks went back on Nov 1, so it is UTC-05:00). The reel's
funnel, 40 sent, 12 replied, 5 interested, shows in status as drafted 40,
sent 40, replied 12 (30% of sent), interested 5, booked 1.
What it never does
- Never sends, and never lets Claude send, without the user's yes for that batch; never "yes to everything from now on"; never from a background task.
- Never writes to anyone without a public source in their row, never guesses an email address, never collects a personal phone number or home address.
- Never emails a thread again after a no, an opt-out or a bounce.
- Never invents a fact in a personal line or a number in a reply.
- Never promises funding. The pack does the work; investors decide.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

