microsoft/draft-outreach
Generates personalized outreach messages by pulling context from Dataverse records. Creates tailored emails for new prospects, re-engagement, follow-ups, or cross-sell. Use when user says "draft an email to [contact]", "write outreach for", "help me reach out to", "compose email", "re-engage this contact", "follow-up email", "prospecting email", or "outreach message for".
npx skills add https://github.com/microsoft/dataverse-business-skills --skill draft-outreach
Generic outreach gets ignored. Personalized messages that reference real context — a recent interaction, a known pain point, or a relevant product already owned — get responses. This skill eliminates the blank-page problem by pulling Dataverse data to craft contextually relevant outreach, saving reps time while improving reply rates. It works within Dataverse without requiring external enrichment tools.
Accept input from the user:
If contact:
SELECT contactid, fullname, firstname, jobtitle, accountid, emailaddress1,
telephone1, description, createdon, modifiedon
FROM contact
WHERE fullname LIKE '%[name]%'
If lead:
SELECT leadid, fullname, firstname, jobtitle, companyname, emailaddress1,
telephone1, description, leadsourcecode, leadqualitycode, createdon
FROM lead
WHERE statecode = 0
AND fullname LIKE '%[name]%'
Present matches if multiple found. Confirm the target with the user before proceeding.
If a contact was found, retrieve their account:
SELECT accountid, name, industrycode, revenue, numberofemployees,
description, address1_city, address1_stateorprovince,
customertypecode, accountcategorycode
FROM account
WHERE accountid = '[accountid]'
Recent activities (last 90 days):
SELECT activityid, activitytypecode, subject, actualend, description,
statecode, regardingobjectid
FROM activitypointer
WHERE regardingobjectid = '[contactid or accountid]'
AND statecode = 1
ORDER BY actualend DESC
Limit to 10 most recent. Note:
Open opportunities:
SELECT opportunityid, name, estimatedvalue, estimatedclosedate, salesstage,
closeprobability, description, currentsituation, customerneed, customerpainpoints
FROM opportunity
WHERE customerid = '[accountid]'
AND statecode = 0
Recently closed opportunities:
SELECT opportunityid, name, estimatedvalue, actualclosedate, statecode, statuscode
FROM opportunity
WHERE customerid = '[accountid]'
AND statecode IN (1, 2)
AND actualclosedate >= '[90_days_ago]'
Products owned (from won opportunities):
SELECT opportunityproduct.productid, product.name, opportunityproduct.quantity,
opportunityproduct.priceperunit, opportunity.actualclosedate
FROM opportunityproduct
JOIN opportunity ON opportunityproduct.opportunityid = opportunity.opportunityid
JOIN product ON opportunityproduct.productid = product.productid
WHERE opportunity.customerid = '[accountid]'
AND opportunity.statecode = 1
SELECT incidentid, title, statecode, prioritycode, createdon, description
FROM incident
WHERE customerid = '[accountid]'
AND statecode = 0
ORDER BY prioritycode ASC
Flag open cases — they affect tone (avoid aggressive outreach to accounts with open escalations).
SELECT taskid, subject, description, scheduledend, statecode
FROM task
WHERE regardingobjectid = '[contactid or accountid]'
AND statecode = 0
ORDER BY scheduledend ASC
If any open tasks exist for this contact, confirm outreach aligns with existing follow-up plan.
Based on gathered context, identify the strongest personalization hooks ranked by specificity:
Tier 1 (most specific — use if available):
Tier 2 (account-level):
Tier 3 (generic fallback):
Select template based on outreach type:
New Intro:
> Subject: [Company] + [Your Company] — [value proposition in 5 words]
>
> Hi [Firstname],
>
> I came across [Account Name] while [researching [industry] leaders / reviewing your profile] and noticed [specific detail from account description or industry].
>
> We help [industry] companies [key value prop relevant to their industry]. [Reference a peer company result if available in Dataverse notes].
>
> Would a 20-minute call make sense to explore if there's a fit? Happy to work around your schedule.
>
> Best,
> [Rep Name]
Re-engagement (contact gone quiet):
> Subject: Re: [Last activity subject] — checking back in
>
> Hi [Firstname],
>
> It's been [n weeks] since we last connected about [last activity subject]. I wanted to check back in — [reference the context from last interaction].
>
> [If open case exists:] I also noticed there's an open [issue] — I've looped in our support team to make sure it's resolved quickly.
>
> Are you still evaluating [solution/need from opportunity]? Happy to reconnect at your convenience.
>
> Best,
> [Rep Name]
Follow-up (after meeting/call):
> Subject: Follow-up: [Meeting subject] — [key next step]
>
> Hi [Firstname],
>
> Thanks for your time [yesterday/on [date]]. A few things from our conversation:
>
> - [Key point 1 from activity description]
> - [Key point 2]
> - [Commitment / next step agreed]
>
> As discussed, [action item] — I'll have that to you by [date].
>
> [If BANT gap identified:] Before our next conversation, it would help to understand [budget / decision process / timeline] so I can tailor our next steps appropriately.
>
> Best,
> [Rep Name]
Cross-sell:
> Subject: [Product already owned] → [New product]: natural next step for [Company]
>
> Hi [Firstname],
>
> Given how you've been using [existing product] since [close date], I wanted to introduce [new product/solution].
>
> Several [industry] customers who started with [existing product] have added [new product] to [specific benefit — e.g., reduce manual work in X process].
>
> Worth a quick call to walk through what it could look like for [Account Name]?
>
> Best,
> [Rep Name]
Tone adjustments:
After generating the draft, offer to create an email activity record:
Use create_record tool with tablename: email
- subject: [Generated subject line]
- description: [Draft body text]
- regardingobjectid: [Opportunity ID or Account ID]
- directioncode: true (outgoing)
- statecode: 0 (draft / open)
- to: [Contact's activityparty reference]
- from: [Current user systemuser reference]
Note: Email is saved as a draft (statecode = 0). Rep reviews and sends from Dynamics 365 or Outlook.
Along with the draft, provide:
Personalization highlights used:
Suggested timing:
Follow-up cadence suggestion:
Provide:
User Input:
"Draft a re-engagement email for Emily Torres at Fabrikam. We haven't talked in 18 days."
Skill Output:
✉️ Draft Outreach — Re-engagement | Emily Torres, Fabrikam
Personalization used:
Subject options:
Draft:
> Hi Emily,
>
> It's been a few weeks since we spoke about the cloud migration. I wanted to check back in — has anything changed with your timeline or the decision process on your end?
>
> I also wanted to acknowledge the API timeout issue that came in — our team is working to resolve it and I'll make sure you have an update by end of this week.
>
> If it helps, I can put together a revised proposal addressing the questions that came up in our last conversation. Would 20 minutes work later this week?
>
> Best,
> Sarah
Sending notes:
Draft saved: Email activity created in Dataverse (ID: email-xxx) — linked to Fabrikam Cloud Migration opportunity. Ready to review and send.
| Table | Purpose |
|-------|---------|
| contact | Target contact details |
| lead | Target lead details |
| account | Account context and firmographics |
| activitypointer | Relationship history |
| opportunity | Open and closed deal context |
| opportunityproduct | Products owned for cross-sell |
| product | Product names |
| incident | Open support cases |
| task | Open follow-up commitments |
| email | Save outreach draft as email activity |
email:
subject (NVARCHAR 200) - Email subject linedescription (MULTILINE TEXT) - Email bodydirectioncode (BIT) - Outgoing(1), Incoming(0)statecode (STATE) - Draft/Open(0), Completed/Sent(1), Canceled(2)regardingobjectid (LOOKUP) - Linked opportunity, account, or contactscheduledstart (DATETIME) - Planned send timecontact:
firstname (NVARCHAR) - For personalized salutationjobtitle (NVARCHAR) - For context and tone calibrationemailaddress1 (EMAIL) - Primary emaildescription (MULTILINE TEXT) - Notes and backgroundUser says: "Draft an intro email to Sarah Chen at Northwind"
Actions:
Result:
To: [email protected]
Subject: Quick thought on Northwind's supply chain initiative
Hi Sarah,
I noticed Northwind recently expanded into the Midwest market —
congratulations on the growth.
We've helped similar distribution companies reduce order
processing time by 40% while scaling operations.
Would you have 15 minutes this week to explore if there's a fit?
Best,
Mike
---
Sending notes:
• Personalized with company expansion context
• Follow up in 3 days if no reply
User says: "Help me reach out to James at Fabrikam again"
Actions:
Result:
To: [email protected]
Subject: Following up on our cloud migration conversation
Hi James,
It's been a few weeks since we discussed your Q2 cloud
migration goals. I wanted to check in — has the internal
budget review wrapped up?
I have a case study from a similar Financial Services company
that might be relevant to share with your CFO.
Happy to reconnect whenever timing works.
Best,
Sarah
---
Context used:
• Last contact: 18 days ago (demo call)
• Open opp: Cloud Migration ($85K)
• Stage: Proposal sent, awaiting budget approval
User says: "Compose a cross-sell email to Alpine Ski House"
Actions:
Result:
To: [email protected]
Subject: Maximize your CRM investment with Analytics
Hi Lisa,
Congratulations on 6 months with our CRM platform — your
team's adoption rate is impressive.
Many customers at your stage add our Analytics module to get
deeper visibility into sales performance. Based on your 200+
open opportunities, you'd likely see immediate value.
Want me to set up a 20-minute demo?
Best,
Mike
---
Cross-sell context:
• Purchased: CRM Platform ($42K) 6 months ago
• Suggested: Analytics Module ($15K)
• Open support cases: 0 (safe to approach)
Cause: Name doesn't match any contact record, or contact is inactive
Solution:
Cause: New contact with no activities or opportunities
Solution:
Cause: Contact has active Priority 1 escalation
Solution:
Take microsoft/draft-outreach from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.