Auto-Enrich Your CRM
Outcome: a repeatable chain that finds the records in Attio with holes or stale titles, fills them from LinkedIn and waterfall enrichment, shows you what it found before anything is written, and updates only the fields that were empty or wrong.
- Surface
- MCP server
- Level
- Intermediate
- Uses
- linkedin_profile_enrich, check_job_change, find_work_email, verify_email, enrich_organization — plus the Attio MCP server
- Credits
- 1 per title refresh, ~1.3 per missing email
- Prerequisite
- Lesson 04, Attio connected to your AI client
The problem this solves
CRM data does not go wrong all at once. It decays — roughly 2–3% of B2B contact records go stale every month, mostly because people change jobs. A year in, a quarter of your database points at someone who left.
Nobody fixes this manually, because the work is invisible until a campaign bounces. So the fix has to be a chain you run on a schedule, not a project someone volunteers for.
Three kinds of broken, and they need different tools:
| Problem | What it looks like | Fix |
|---|---|---|
| Missing | Email or LinkedIn URL is empty | find_work_email, find_linkedin_from_work_email |
| Stale | Title says SDR, they are now a manager elsewhere | linkedin_profile_enrich, check_job_change |
| Unusable | Email present but undeliverable | verify_email |
The chain
Pull only the broken records
Filter inside Attio, not after. Ask for People where email is empty, or where job_title has not been touched in 12 months, or where a list is scoped to one segment.
Pulling 5,000 records to fix 300 is how a 400-credit job becomes a 6,500-credit one. Capture the record ID on every row — without it there is nothing to write back to.
Refresh what changed
linkedin_profile_enrich at 1 credit returns the current title and company for a LinkedIn URL. Compare it against what Attio holds; anything different is the thing you are here for.
For records where you specifically want the event rather than the current state, check_job_change at 2 credits answers “did this person move?” directly — a moved champion is a pipeline signal, not just a data fix. That play is Job Changes & Champions.
Fill the gaps
Missing emails through find_work_email, then verify_email on both the new ones and any existing address you do not trust. Missing company firmographics through enrich_organization.
Review before writing
A table of proposed changes: record ID, field, old value, new value, source, confidence. This step is not optional — see the rule below.
Write back, field by field
Only the confirmed rows, only the fields that were empty or provably stale. Never a blanket overwrite.
Run it
Use the Attio MCP server and the Sync GTM MCP server.
PULL
Get People records from Attio where job_title is empty OR last updated
more than 12 months ago. Limit 100. Include the record ID, name,
current job_title, company, email and linkedin_url on every row.
Show me the count before going further.
REFRESH — Sync GTM
For each record with a LinkedIn URL, run linkedin_profile_enrich and
return the current title and company.
For each record with no email, run find_work_email, then verify_email.
Do not guess email patterns. Skip rows with no result.
COMPARE
Build a table: record ID, field, Attio value, new value, source tool.
Only include rows where the new value differs from the Attio value or
the Attio field was empty. Report credits used.
DO NOT WRITE ANYTHING TO ATTIO YET.Read the table. Then, in a second message:
Write these back to Attio, one record at a time. Only update fields that
were empty or that we confirmed changed. Do not overwrite any field
where Attio already holds a value we did not verify. Confirm each write
and report any that failed.The uppercase line in the first prompt is load-bearing. A chain that reads and writes in one message will have written before you see the diff — and a CRM write is the one step here with no undo. Two messages, always.
The rule: never overwrite what you did not verify
A blank field is a gap. A populated field is somebody’s work — a rep typed it, or a form captured it, and it may be right in a way no provider knows.
So the write step gets three constraints:
- Empty fields: fill freely.
- Populated fields: only overwrite when enrichment returned something different and you can name the source.
- Everything else: leave alone, even when the new value looks better.
Write the source and date into the record where your schema allows — an enriched_at and enriched_by field turns “where did this title come from?” into a lookup instead of an argument. It also gives your next run something honest to filter on.
What it costs
For 100 records that need work:
| Job | Per record | 100 records |
|---|---|---|
| Title and company refresh | 1 | 100 |
| Missing email, found and verified | 1.3 | 130 |
| Job-change check | 2 | 200 |
| Company firmographics | 2 | 200 |
Do not run all four on everything. Refresh titles across the base, chase emails only on records you will actually contact, and reserve job-change checks for closed-won contacts and past champions — that is where a move is worth money rather than tidiness.
Check your work
| Check | How |
|---|---|
| You pulled the broken ones | Record count ≈ your known gap, not your whole database |
| Diffs are real | Spot-check five changed titles against their LinkedIn profiles |
| Nothing good was destroyed | Pick three records that already had values and confirm they are untouched |
| Writes landed | Re-pull five updated records from Attio and read them back |
| Cost matches the work | Credits ≈ per-record cost × records that actually needed fixing |
Where this breaks
Records with no LinkedIn URL and no work email cannot be resolved by this chain — there is nothing to look up from. Route them to a name-plus-company search instead of letting the chain guess, and expect a lower hit rate.
Duplicate records will each get enriched separately, and you will pay twice for the same person. Dedupe by email or LinkedIn URL inside Attio before running this, not after.
A hundred records is a comfortable batch. A model asked to reconcile a thousand rows in one context will start dropping them silently — and a silently dropped row looks exactly like a row that needed no change. Batch it, and check the counts between batches.
Making it recurring
Once the chain is right, the value is in the cadence rather than the run:
- Monthly — title and company refresh across active contacts
- Weekly — email fill and verification on anything entering a sequence
- Quarterly — job-change sweep across closed-won and past champions
The same job at CRM scale belongs in a table rather than a chat window: pull records in with the CRM integration, enrich the columns, push back, and let it re-run on a schedule. CRM Enrichment builds exactly that, and Attio is native there — no second MCP server, because it runs on Sync GTM credits.
Further automation
One skill per CRM, each already carrying the review step and the no-overwrite rule:
- Attio Enricher — this lesson, as a single command
- HubSpot Enricher, Salesforce Enricher, Close Enricher — the same chain against the other CRMs
- Job Change Detector — the champion-tracking half on its own
- Email Verifier — deliverability sweeps before a send
Where to next
That is the third build. All three — outbound, research and this one — are the same shape: source cheaply, filter for free, spend on survivors, review before anything irreversible.
Reference for this lesson: Prompting guide, Tools, CRM integrations, CRM Enrichment, Job Changes & Champions.