| name | sales-agent |
| description | Use whenever a used-machinery dealer just acquired a machine (or has an unsold one) and needs to figure out who to pitch it to. Before drafting anything, the agent scans the dealer's Gmail for buyer signals (RFQs, "looking for", capability inquiries, prior interest in this brand/tonnage/type), cross-references the dealer's customer list (Google Sheet), and surfaces a ranked shortlist of 3–7 buyers to approach. Then it drafts a personalized outreach email per buyer, referencing what they previously bought, asked about, or expressed interest in. Triggers on "who should I pitch this to", "find buyers for the Engel", "draft outreach for the Krauss-Maffei", "remind me who's looking for a 200-ton IMM", "who needs a CNC lathe", "list my customers", "add this customer", "build my customer list", or any moment the dealer has a machine and is asking "who?". NOT for cold-outreach mass blasts — this skill is curated, one-machine, who-do-I-know-that-buys-this. |
Sales Agent
The dealer's personal "who do I sell this to?" brain. Combines (a) the dealer's Gmail history (who's been asking about machines lately), (b) the dealer's customer book (what they've bought before, what they typically run), and (c) the new machine's specs — to produce a curated, ranked outreach list with drafts already written.
When this fires
- "I just bought a Krauss-Maffei CX 160 — who should I call?"
- "Find buyers for the Engel Victory 200"
- "Who's been asking about IMMs in the 150-250 ton range?"
- "Draft outreach for the Haitian — pull from my customer list"
- "Add Midwest Molding to my customers, they bought the CX 110 last year"
- "Remind me who I sold Krauss-Maffei to in the last 2 years"
- "Show me my hot leads — anyone reach out about CNCs?"
First-run setup
If /mnt/user-data/uploads/.dealer_sales_sheet.json doesn't exist, run setup:
- Google Sheet — "Do you already have a customer / sales tracking Google Sheet? Paste the ID (the long string between
/d/ and /edit in the URL). If not, I'll create one — give me the title and I'll set up the tabs."
- If creating: use
scripts/bootstrap_sheet.py to create the sheet with the standard tab structure (see below). Requires Google service account JSON at /mnt/user-data/uploads/.google_service_account.json. If missing, prompt: "Drop your service account JSON at that path and share the sheet with the service account email."
- Cache the result:
{
"sheet_id": "1AbCdEf...",
"sheet_title": "Premier Equipment — Sales & Customers",
"tabs": {
"customers": "Customers",
"sales": "Sales",
"leads": "Leads",
"outreach_log": "Outreach Log"
},
"owner_email": "nate@premier-equipment.example",
"created_at": "2026-05-28T03:00:00",
"service_account_email": "claude-sheets@<proj>.iam.gserviceaccount.com"
}
Sheet structure (created by bootstrap)
Customers tab — the dealer's book.
| Column | Notes |
|---|
customer_id | Auto: slugified company name |
company | Required |
primary_contact | Name |
email | Required for outreach |
phone | |
city, state | Location for rigging proximity later |
equipment_focus | Comma-separated: injection_molding,cnc,presses |
tonnage_range | e.g. 100-300t for IMM customers |
last_purchase_date | |
last_purchase_machine | What they bought from us |
last_contact_date | Any contact, not just purchase |
credit_terms | wire_on_po, net30, etc. (matches sales-proposal cache) |
notes | Open field — preferences, decision-maker, gotchas |
status | active, dormant, lost, prospect |
Sales tab — managed by past-sales-agent (see that skill). Both skills share this sheet.
Leads tab — Gmail-discovered buyer interest that hasn't matured into a customer yet (RFQs, "do you have", capability questions). Schema: discovered_at, email_from, company_guess, interest_type, equipment_mentioned, urgency, gmail_thread_id, status (new, contacted, quoted, converted, dead).
Outreach Log tab — every pitch sent. Schema: sent_at, customer_id, machine_offered, subject_line, personalization_signal, response_status, notes.
Per-request flow ("who do I pitch this to?")
- Get the machine — title, type (IMM/CNC/etc.), tonnage/spec, year, location, asking price. If the dealer just used
imm-spec-agent or sales-proposal on this machine, pull the details from there.
- Scan Gmail FIRST (before touching the customer sheet) —
scripts/scan_gmail_for_leads.py emits a search plan. Use the Gmail MCP search_threads to run these queries:
<machine brand> OR <machine type> in last 90 days
"looking for" OR "do you have" OR "RFQ" near <machine type>
<tonnage> ton OR <spec keyword> in last 180 days
- For top responses, pull thread + extract: sender email, company, what they asked for, urgency signals (timeline mentions). Auto-write fresh hits to the Leads tab unless already present.
- Score the customer book —
scripts/score_customers.py ranks customers by:
- Equipment focus match (IMM customer + IMM machine = high)
- Tonnage / spec range match
- Recency of last contact (penalty if >12 months silent)
- Status (
active > dormant > lost)
- Past purchase from this brand
- Blend leads + customers — present a ranked top 5–7. For each: company, contact, the signal that puts them on the list ("Asked about 200-ton IMMs 6 weeks ago" / "Bought a CX 110 in 2024 — they run KraussMaffei").
- Draft outreach — for each prospect the dealer approves,
scripts/draft_outreach.py writes a personalized email:
- Opens referencing the personalization signal (not "hope you're well")
- States the machine in one specific sentence (year, tonnage, hours/cycles if known, condition phrasing matching the blind-deal posture)
- Names the price and what's included (rigging/freight if applicable)
- One soft CTA — "want me to send the spec sheet?" not "BUY NOW"
- Signed with the dealer's brand cache contact info
- Log outreach when the dealer sends — append a row to Outreach Log so we don't double-pitch.
Anti-patterns
- ❌ Drafting before scanning Gmail — the freshest signal is always in inbox, not in the sheet.
- ❌ Generic "hope you're well" openers. The whole point of this skill is the personalization signal — surface it in the first line.
- ❌ Mass blast. Cap at 7 prospects per machine; if the dealer asks for more, ask why — usually the answer is "broaden the criteria," not "send to everyone."
- ❌ Pitching customers in
status: lost without flagging it ("Note: this customer is marked LOST in 2023 — proceed?").
- ❌ Forgetting to attach
sales-proposal skill output if the dealer asks for "the actual PDF" — call that skill, don't reinvent.
File map
scripts/sheet_client.py — Google Sheets API wrapper (gspread); shared with past-sales-agent
scripts/bootstrap_sheet.py — creates the sheet + tabs + headers on first run
scripts/scan_gmail_for_leads.py — emits Gmail search plan; writes hits to Leads tab
scripts/score_customers.py — ranks customer book against the current machine
scripts/draft_outreach.py — generates personalized email drafts
references/setup.md — Google service account walkthrough
Companion skills
past-sales-agent — shares the same sheet, reads Sales tab to inform "this customer bought X from us in 2024"
sales-proposal — invoked when a prospect says "send me a quote"
rigging-agent — once a buyer is locked, find the rigger near the seller's facility