---
name: moltsets-hubspot-buying-committee-expansion
description: Use this skill on an open HubSpot deal to find the stakeholders you do not yet have, enrich them with MoltSets, and create them as contacts associated to the deal.
---

# HubSpot Buying Committee Expansion

Surface the rest of the buying committee for an open HubSpot deal. Starting from the deal's associated company, search MoltSets for people in the target titles and seniority levels, dedupe them against the contacts already on the deal, fill email gaps, create the new contacts in HubSpot, and associate each one to the deal and company. It finds the stakeholders your reps did not know to look for.

## Triggers

"For this open deal, find the rest of the buying committee and add them as contacts", "expand this HubSpot deal with VP and Director stakeholders at the same company". Use when the user wants to widen coverage on an open deal to the full buying committee.

## Requirements

- HubSpot remote MCP (mcp.hubspot.com) and the MoltSets MCP connected in the same client
- Custom objects are not reachable through HubSpot's remote MCP - create standard contact records and standard associations

## Chain

```
HubSpot open deal
  -> hubspot/get-object                (deal + associated company domain)
  -> hubspot/list-associations         (existing contacts on the deal, for dedupe)
  -> MoltSets:
       search_people                   (company_domain + target titles / seniority / department)
  -> dedupe against existing contacts + suppression rules
  -> linkedin_to_best_email            (fill email gaps where search_people has none)
  -> hubspot/create-object             (create new contacts)
  -> hubspot/associate-objects         (associate each contact to the deal + company)
```

## Inputs

- **Deal** - the HubSpot deal to expand, or a filter for a set of open deals
- **Target roles** - the titles, seniority levels, and departments that make up your buying committee
- **Coverage** - how many contacts per account to add, and any hard caps
- **Suppression rules** - domains, existing contacts, and do-not-contact lists to exclude
- **Acceptable risk scores** - which A-F deliverability grades to keep (recommended: A, B, C and F; D excluded)

## Risk scores - confirm before enriching

Every email MoltSets returns carries a deliverability risk score - a grade from A to F. Ask which grades to keep before running anything:

> "MoltSets grades email deliverability risk from A (best) to F (no data). Which grades should I keep? I'd recommend **A, B, C and F** - and dropping **D**, since D is a confirmed bounce, complaint or spam trap."

| Grade | Meaning | Best practice |
| --- | --- | --- |
| A | Strongest engagement signal available | Safe to send immediately |
| B | Solid | Fine in regular sends; on a new or warming domain, send a smaller batch before scaling |
| C | Deliverability can't be confirmed | Segment separately from A/B, warm at low volume, watch engagement, suppress non-responders after 1-2 attempts |
| D | Confirmed bounce, complaint or spam trap | Never send - fastest way to trip spam traps and damage sender reputation for the whole list |
| F | No data - unknown risk, not "safe" | Re-verify before sending, or treat like C |

Use whatever set the user confirms. Treat the grade as a filter, not a guarantee - it lowers risk, it doesn't remove it. Pair it with the user's own sending domain reputation and list hygiene.

## `search_people` filter notes

- **Filters are free precision.** Execution cost comes from the free-text `query`, not the filters attached to it. A filters-only call (no `query`) runs **~40x cheaper**; a bare `query` is the least precise shape available and no cheaper than a filtered one. Never send `query` alone - at minimum attach `country` (~99% filled). Billing is unchanged either way: tokens are charged per record returned.
- **Full filter set:** `query`, `company`, `company_domain`, `country`, `state`, `city`, `seniority`, `department` *or* `functional_area` (same underlying data - never both), `industry`, `linkedin_industry`, `naics_code`, `employee_range`, `revenue_range`, plus `limit`/`offset`.
- **`employee_range` and `revenue_range` apply to the person's current employer**, so you can target by company size or revenue without a `search_companies` pass first. Prefer the numeric bands over legacy `"Small"`/`"Mid-Market"`/`"Enterprise"`/`"Unknown"`.
- **Three industry vocabularies:** `industry` (21 broad buckets), `linkedin_industry` (LinkedIn's ~150 niche labels), `naics_code` (any hierarchy level - "54" broad, "541120" surgical). Pick the one matching how specific the targeting actually is.
- **Fill rates:** `country` ~99%, `title` ~85%, `headline` ~65%, `seniority`/`industry`/`department` ~60%, `naics_code`/`linkedin_industry` ~50%. Every filter is exact-match and silently drops records with an empty field, so stacking three sparse ones can zero out a viable audience. Widen by dropping the sparsest filter first, not `country`.
- **Exact strings:** `"C Suite"` (space, not hyphen), `"Marketing & Advertising"`, `"Medical & Health"`, `"Texas"` not `"TX"`, `"United Kingdom"` not `"UK"`.
- **Size before you walk.** `search_linkedin_profile` with `count_only: true` returns a match count free of tokens; every search response carries `results.total`. Results are `_score`-ranked - the first page is the best page, 25 max per call.
- **Emails are already in the results** - records carry `business_email` and `business_email_risk_score`, so those rows need no enrichment call.

## Steps

1. Read the deal and resolve the associated company's domain.
2. List the contacts already associated to the deal so they can be excluded from the results.
3. Run `search_people` filtered on the company domain plus your target titles (via `query`), `seniority`, and `department` filters.
4. Dedupe the returned people against existing deal contacts and your suppression rules.
5. Use the `business_email` returned by `search_people` where present, and run `linkedin_to_best_email` to fill any gaps.
6. Create the new contacts in HubSpot and associate each one to the deal and its company.

Before any write-back, every found address is checked against the accepted grade set. Out-of-range grades are reported in the table with their true score and skipped - never written to the CRM.

## Output

| Name | Title | Seniority | Company | Email | Risk | LinkedIn | New/Existing | Associated To Deal |
| --- | --- | --- | --- | --- | --- | --- | --- | --- |

Show the risk score on every row that has an email, including grades outside the accepted set - flag those in `Action` (e.g. "held - grade D") rather than dropping them silently. Only emails inside the accepted set are written back to the CRM.

```
Deal company:            X
Existing contacts:       X
Candidates found:        X
New contacts added:      X
Emails found:            X/N (XX%)
MoltSets tokens used:    X

Email risk scores:
  A: X   B: X   C: X   D: X   F: X
  kept (accepted grades):  X
  filtered (excluded):     X
```

## Tips

- `search_people` returns a business email in many records, so check that field before spending a token on a separate email call.
- Use `company_domain` for the account match rather than free-text company name, since domain is exact.
- Set a per-account cap so a large company does not flood the deal with dozens of loosely relevant contacts.
- Creating and associating records changes the deal, so run a dry-run pass and confirm before writing.
