# Company People List

> Build an intelligent people map for a target company by combining Attio CRM, LinkedIn (Anysite MCP), Extruct enrichment, Gmail, and Granola meeting notes. Goes beyond a flat list — reads deal notes, email threads, and meeting history to classify each person's role and relevance to the deal. Outputs a CSV with Name, Title, LinkedIn URL, Deal Role, and Relevance Notes. Triggers on: "map out [company]", "org chart", "who works at [company]", "people at [company]", "company people list", "team map", "stakeholder map", "who should we talk to at [company]", "who can influence the deal at [company]", "build a contact list for [company]", even just "[company] org".

- Skill: `extruct-ai/company-people-list` (Agent Skill)
- Install (CLI): `npx skillmds@latest add extruct-ai/company-people-list`
- Raw SKILL.md: https://api.skillmd.com/api/skills/extruct-ai/company-people-list/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Product & Planning
- Author: extruct-ai (https://skillmd.com/u/extruct-ai)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/extruct-ai/company-people-list

---


# Company People Map

Build a stakeholder map for a target company. This is not a flat contact dump — it's
an intelligence product. Every person gets classified by their relevance to the deal,
and the output tells the user who matters, who to bring into the conversation, and why.

## Why This Matters

A raw list of names and titles is useless for sales. What you need is to understand:
- Who is your **champion** (actively pushing for your product internally)?
- Who is the **decision maker** (has budget authority or final say)?
- Who are the **end users** (will actually use the product day-to-day)?
- Who are **influencers** (can sway the decision one way or another)?
- Who is **net new** (not yet in any conversation but worth reaching out to)?

The deal context from emails, meetings, and CRM notes is what transforms a contact
list into an actionable map.

## Data Sources

| Source | What it provides | Tool |
|--------|-----------------|------|
| **Attio** | CRM contacts, deal records, interaction history, connection strength | MCP connector |
| **Anysite** | LinkedIn profiles, current titles, who actually works there now | MCP connector |
| **Extruct** | Enriched company data from Company CRM table | MCP connector |
| **Gmail** | Email threads — who's been in conversations, what's been discussed | MCP connector |
| **Granola** | Meeting notes — what was said, action items, who attended | MCP connector |

## Output Format

A CSV file with these columns:

```
Name,Title,LinkedIn URL,Deal Role,Relationship Status,Relevance Notes,LinkedIn Activity & Insights
```

- **Name**: Full name
- **Title**: Current job title at the target company (verified from LinkedIn when possible)
- **LinkedIn URL**: Profile URL
- **Deal Role**: One of: Champion, Decision Maker, End User, Influencer, Gatekeeper, Net New
- **Relationship Status**: One of: Active (recent interaction), Warm (past interaction), Cold (no interaction), Unknown
- **Relevance Notes**: 1-2 sentence explanation of why this person matters and what you know about them
- **LinkedIn Activity & Insights**: What their posting behavior reveals about how to approach them (for key people only)

## Workflow

### Step 1: Understand the Deal Context First

Before pulling any people data, understand what you're selling and where the deal stands.
This context is essential for classifying people later.

#### 1a. Find the deal in Attio
Use `search-records` with `object: "companies"` to find the company, then check
`associated_deals` on the company record. Fetch the deal with `get-records-by-ids`
on `object: "deals"`.

Extract: deal name, stage, type, confidence, owner, associated people, associated company.

**Important:** Also check for duplicate company records in Attio. Search returns multiple
records sometimes — fetch ALL of them and collect ALL team member IDs across duplicates.
The "primary" record is the one with the most data (domains, description, most team members).

#### 1b. Read deal notes
Use `search-notes-by-metadata` with `parent_record_object: "deals"` and the deal record ID.
Then `get-note-body` for each note. Also check company-level notes.

#### 1c. Read email history
Use Gmail MCP: `gmail_search_messages` with `from:{company-domain} OR to:{company-domain}`.
Then `gmail_read_thread` on the most important threads (look for deal discussion threads,
not just calendar invites).

From emails, extract:
- Who is on the To/CC lines (these are the active players)
- What topics are being discussed
- What commitments have been made
- What objections or delays have come up
- Who introduced whom

#### 1d. Check meeting notes
Use Granola MCP: `query_granola_meetings` with the company name.
Then `get_meetings` for details on relevant meetings.

From meetings, extract:
- Who attended
- What was discussed
- Action items assigned to whom
- Decisions made

#### 1e. Synthesize the deal context
Before proceeding, write a brief internal summary:
- What product/service are we selling to this company?
- What stage is the deal at?
- Who have we been talking to so far?
- What are the key dynamics (delays, competing tools, budget concerns)?

This summary drives how you classify people in Step 3.

### Step 2: Pull People from All Sources

#### 2a. Attio — ALL team members across ALL company records
Collect people record IDs from the `team` field of EVERY company record matching
this company (including duplicates). Fetch them all with `get-records-by-ids`.

For each person, note:
- Name, job title, LinkedIn URL, email
- `strongest_connection_strength` (tells you relationship quality)
- `last_interaction` date
- `origin` (Registration, Outbound, Event, etc.)
- Whether they're `associated_people` on the deal record (directly involved)

#### 2b. Anysite — LinkedIn employee search
Use `execute` with `source: "linkedin"`, `category: "search"`, `endpoint: "search_users"`,
`params: { "current_company": "<company-name>", "count": 50 }`.

**Critical: Filter out non-employees.** LinkedIn's `current_company` search returns
people who have the company mentioned anywhere in their profile — including board members,
advisors, portfolio companies' founders, and people who left. You MUST analyze each
result's headline to determine if they actually work there:

**Keep** if headline contains patterns like:
- "[Role] at [Company]" or "[Role] @[Company]"
- "[Department] at [Company]"
- Just a role that aligns with the company type (e.g., "Investor" for a VC firm)

**Filter out** if headline suggests they work elsewhere:
- "CEO at [Other Company]" (even if they mention the target as investor/advisor)
- "Founder of [Other Company]"
- "Partner at [Other Company]"
- Mentions of the target company only as investor, advisor, or board role
- "Ex-[Company]" or "Former [Company]"

For a VC firm specifically, keep: Partners, Principals, Associates, Analysts, Operations,
Platform, Marketing/Comms, Fundraising, Legal, Finance roles. Filter out: Portfolio
company founders, LPs, advisors who work elsewhere.

#### 2c. Extruct — Check enrichment tables
If the Extruct MCP is connected, check the Company CRM table and Reverse Lookup table
for people associated with the company. Use `get_table_data` with the cached table IDs
from `.env` (`EXTRUCT_COMPANY_CRM_TABLE_ID`, `EXTRUCT_REVERSE_LOOKUP_TABLE_ID`).

Note: The Extruct MCP may not be configured in every environment. If the tools aren't
available or return no results, skip gracefully and note it in the output summary.

### Step 3: Classify Each Person

This is the most important step. For every person in the merged list, assign a **Deal Role**
and **Relationship Status** based on the context gathered in Step 1.

#### Deal Role classification:

**Champion** — Someone actively advocating for your product internally.
Signs: they signed up for the product, they schedule meetings, they send data/files,
they bring colleagues into the conversation, they respond quickly to emails.

**Decision Maker** — Has authority over budget or final purchasing decision.
Signs: senior title (Partner, Managing Partner, VP, Head of), mentioned in deal context
as approver, signs contracts.

**End User** — Will use the product day-to-day if the deal closes.
Signs: their role matches the use case (e.g., analysts for a deal sourcing tool),
they're mentioned as "the team" who will trial the product.

**Influencer** — Can sway the decision but doesn't have final authority.
Signs: CC'd on emails but doesn't lead conversations, attends meetings but isn't
the primary contact, their role intersects with the product's value prop.

**Gatekeeper** — Controls access to decision makers or manages procurement.
Signs: operations/admin role, handles scheduling, manages tool evaluations.

**Net New** — Found on LinkedIn or Extruct but no interaction history. Worth reaching out to
based on their role relevance.
Signs: no email history, not in Attio, but their title suggests they'd benefit from
or influence the purchase of your product.

#### Relationship Status:

- **Active**: Interaction in last 30 days (email, meeting, or CRM update)
- **Warm**: Interaction in last 90 days
- **Cold**: Interaction older than 90 days, or was contacted but didn't engage
- **Unknown**: No interaction history (net new from LinkedIn)

#### Relevance Notes:

Write 1-2 sentences explaining what you know about this person's relationship to the deal.
Ground every note in actual data — cite specific emails, meetings, or CRM records.
Examples:
- "Main point of contact. Signed up for product trial, shared sample data for testing,
  scheduled onboarding. Actively pushing trial with analyst team."
- "CC'd on all deal emails since initial outreach. Accepted demo meeting. Operations role
  suggests she coordinates tool evaluations."
- "Head of Department — relevant because the product directly serves their workflow.
  No interaction yet. Worth a targeted outreach."
- "VP of Engineering. Ultimate decision maker for platform purchases. No direct interaction
  but should be aware of the trial."

### Step 4: Merge, Deduplicate, and Generate Output

#### Dedup strategy:
1. Match on LinkedIn URL (normalize: lowercase, strip trailing slash)
2. Fallback to name match (case-insensitive)
3. When merging: prefer Attio for name, LinkedIn for title/URL, combine relevance notes

#### Generate CSV
Sort by Deal Role priority: Champion → Decision Maker → End User → Influencer →
Gatekeeper → Net New. Within each role, sort by Relationship Status: Active → Warm →
Cold → Unknown.

Use Python for proper CSV escaping. Save to the workspace folder.

### Step 5: Enrich with LinkedIn Activity

For the most important people (Champions, Decision Makers, key Influencers, and high-value
Net New contacts), pull their recent LinkedIn posts and analyze what they're talking about.

#### 5a. Get user URNs
For each person, call Anysite `execute` with `source: "linkedin", category: "user",
endpoint: "user"` using their LinkedIn alias. You need the `urn` (fsd_profile) from
the response to query posts.

#### 5b. Pull recent posts
Call `execute` with `source: "linkedin", category: "user", endpoint: "user_posts"`,
passing the URN and `count: 10`. Use `posted_after` with a Unix timestamp (e.g.,
6 months ago) to get recent activity only.

#### 5c. Analyze posts for deal-relevant signals
For each person's posts, look for:

- **Thematic alignment**: Are they posting about topics related to what you're selling?
  (e.g., if selling deal sourcing tools, are they posting about data-driven VC, AI in investing?)
- **Hiring signals**: Are they hiring for roles your product supports?
- **Event activity**: Are they attending/speaking at relevant conferences?
- **Portfolio activity**: What companies are they championing? Any overlap with your product?
- **Engagement patterns**: High follower count + frequent posts = influential voice internally
- **Repost patterns**: What companies and people do they amplify? This reveals internal priorities
- **Content gaps**: If a decision maker never posts, note it — they may need a different outreach approach

#### 5d. Write activity insights
Add a "LinkedIn Activity & Insights" column to the CSV. Write 2-3 sentences summarizing
what their posting behavior tells you about how to approach them. Always end with a
"KEY INSIGHT" — one actionable takeaway.

Examples:
- "Very active poster about data-driven VC and deal sourcing with AI. Speaks at industry
  events on this exact topic. KEY INSIGHT: Already an evangelist for this category —
  frame the product as supporting his existing narrative."
- "No recent posts, minimal public profile. KEY INSIGHT: Low social media
  activity — best approached via warm intro through champion, not cold outreach."
- "Posts about AI & Infra investments, hosts founder mixers across Europe. KEY INSIGHT:
  Thematically the most aligned partner — re-warm the cold connection through product demo."

### Step 6: Save to Attio as a Deal Note

Create a note on the deal record in Attio using `create-note` so the analysis lives
in the CRM alongside the deal history. This is the most important output — the CSV
is the backup, the note is what the team actually reads.

Use `parent_object: "deals"` and the deal record ID from Step 1a.

#### Note structure (markdown):

```
## Stakeholder Map — [Company] ([Month Year])

**Deal:** [deal name] — [stage] (confidence [X])
**Generated:** [date]
**Full spreadsheet:** [link to CSV or Google Sheet]

---

## Key Players

**[Name]** — [Deal Role] ([Relationship Status])
[Title]. [2-3 sentences of reasoning grounded in emails, meetings, CRM data,
and LinkedIn activity. Include the KEY INSIGHT from LinkedIn analysis.]

[Repeat for top 3-5 people]

---

## What LinkedIn Activity Tells Us

- **[Name]**: [1-sentence insight about their posting behavior and what it means
  for approach strategy]
[Repeat for each person whose LinkedIn was analyzed]

---

## Expansion Opportunities

1. **[Name]** — [Why they matter and how to reach them]
[Repeat for top 3-5 expansion targets]

---

## Approach Recommendations

- **[Name]**: [Specific action — e.g., "Re-engage via product demo", "Let trial
  results speak, then escalate through champion"]
[Repeat for each key person]

---

## Gaps

- [What's missing — no CRM notes, contacts who may have left, missing data sources]

---

*[X] people mapped across Attio, LinkedIn, and email. Full details in the CSV.*
```

#### Key principles for the note:

- **Ground everything in data**: Never write "might be relevant" without citing
  an email, meeting, LinkedIn post, or CRM field
- **Be opinionated**: The note should tell the reader exactly who to talk to and how.
  Don't hedge with "could be useful" — say "approach via warm intro through the champion"
- **Keep it scannable**: Use bold names, dashes, and short paragraphs. This will
  be read on a CRM screen, not printed
- **Date it**: Include generation date so the team knows when this was last updated
- **Link the spreadsheet**: Reference the CSV file path or Google Sheet URL so the
  reader can dig into the full data

### Step 7: Present the Map to the User

Don't just drop a CSV link. Present the findings as a brief intelligence summary:

1. **Deal snapshot**: What's the deal, what stage, what's the latest.
2. **Key players** (2-4 people): The most important contacts with context.
3. **What they're talking about**: Key LinkedIn activity insights — what signals did you find?
4. **Expansion opportunities**: Net new people worth reaching out to, with reasoning.
5. **Approach recommendations**: For each key person, how should the user approach them based on their LinkedIn activity and relationship status?
6. **Gaps**: What you don't know — missing decision makers, unclear org structure, etc.
7. **CSV link**: The full detailed list for reference.
8. **Attio note confirmation**: Confirm the note was created on the deal with the note title.

## Environment

| Variable | Source | Purpose |
|----------|--------|---------|
| Attio | MCP connector | CRM data, deals, people, notes |
| Anysite | MCP connector | LinkedIn search and profiles |
| Gmail | MCP connector | Email thread history |
| Granola | MCP connector | Meeting notes and transcripts |
| Extruct | MCP (`https://api.extruct.ai/mcp`) | Company/people enrichment tables |

## Key Attio Fields

- Company: `name`, `domains`, `linkedin`, `team` (linked people), `associated_deals`
- People: `name`, `job_title`, `linkedin`, `email_addresses`, `company`, `strongest_connection_strength`, `last_interaction`, `origin`
- Deals: `name`, `stage`, `deal_type`, `deal_confidence`, `associated_people`, `associated_company`, `owner`

## Anysite LinkedIn Reference

- Company lookup: `source: "linkedin", category: "company", endpoint: "company"`
- Employee search: `source: "linkedin", category: "search", endpoint: "search_users"`
- User profile: `source: "linkedin", category: "user", endpoint: "user"`
- User posts: `source: "linkedin", category: "user", endpoint: "user_posts"` (requires URN from user endpoint)
- User comments: `source: "linkedin", category: "user", endpoint: "user_comments"` (requires URN)

Always call `discover` before `execute` if unsure of endpoint params.

## Reference

- Extruct Company CRM table: read `EXTRUCT_COMPANY_CRM_TABLE_ID` from `.env`, fetch via `get_table_data`
- Extruct Reverse Lookup table: read `EXTRUCT_REVERSE_LOOKUP_TABLE_ID` from `.env`, fetch via `get_table_data`

