Matches email addresses and meeting attendees to CRM contacts using progressive matching. Activates when the user needs to identify which client an email belongs to, resolve a contact, or look up a client from an email address. Uses a 5-step algorithm from exact email match to fuzzy name matching with confidence scoring.
From founder-osnpx claudepluginhub thecloudtips/founder-os --plugin founder-osThis skill uses the workspace's default tool permissions.
references/matching-patterns.mdDesigns and optimizes AI agent action spaces, tool definitions, observation formats, error recovery, and context for higher task completion rates.
Enables AI agents to execute x402 payments with per-task budgets, spending controls, and non-custodial wallets via MCP tools. Use when agents pay for APIs, services, or other agents.
Compares coding agents like Claude Code and Aider on custom YAML-defined codebase tasks using git worktrees, measuring pass rate, cost, time, and consistency.
Resolve email addresses, attendee names, and domain names to CRM Pro client records in Notion. The matching algorithm uses a progressive strategy: start with exact matches (highest confidence), fall back to domain matching, then fuzzy name matching. Each match receives a confidence tier to indicate reliability.
This skill is consumed by all three plugin commands (crm:sync-email, crm:sync-meeting, crm:context). The commands pass in raw participant data (email addresses, display names, attendee lists) and receive structured match results with confidence scores. The skill handles only the matching logic -- it does not create or modify CRM records.
Use dynamic database discovery for all lookups. Search by database title -- never hardcode database IDs.
Search for a database titled "[FOS] Companies", "Founder OS HQ - Companies", "Companies", or "CRM - Companies" (in that priority order). Key properties for matching:
Search for a database titled "[FOS] Contacts", "Founder OS HQ - Contacts", "Contacts", or "CRM - Contacts" (in that priority order). Key properties for matching:
Process each participant through these steps in order. Stop at the first step that produces a match with confidence HIGH or above. Continue through all steps only when earlier steps fail or produce MEDIUM or lower confidence.
From the email address, extract the domain portion after the @ symbol.
@. Take the right-hand portion as the raw domain.www., mail., or email. if present.${CLAUDE_PLUGIN_ROOT}/skills/crm/client-matching/references/matching-patterns.md). If the domain is personal, mark it as non-matchable by domain and skip directly to Step 4.@) against the distribution list patterns (see ${CLAUDE_PLUGIN_ROOT}/skills/crm/client-matching/references/matching-patterns.md). If it matches a distribution list pattern, skip this participant entirely -- distribution addresses do not represent individual contacts.Use the normalized domain from Step 1 to search the Companies database.
www. prefix. If the domain is acme.com, also search for www.acme.com and https://acme.com.Search the Contacts database for a record matching the full email address.
When Steps 2 and 3 fail (personal email domain or no domain/email match), attempt name-based matching.
From: "Jane Smith" <jane@gmail.com>) or meeting attendee name field.., -, _ delimiters. Capitalize each part. Skip this derivation if the local part appears to be a username rather than a name (e.g., "cooldude99").${CLAUDE_PLUGIN_ROOT}/skills/crm/client-matching/references/matching-patterns.md: handle initials, nickname variants, and hyphenated names.When all previous steps fail, return an unmatched result.
| Tier | Score | Meaning | Match Method |
|---|---|---|---|
| EXACT | 1.0 | Full email address verified in Contacts DB | Email → Contact → Company |
| HIGH | 0.8 | Domain matched to a Company in the CRM | Domain → Company, contact not verified |
| MEDIUM | 0.6 | Domain matched to Company but contact not in CRM | Domain → Company, unknown contact |
| LOW | 0.4 | Fuzzy name match only, no email or domain confirmation | Display name → Contact or Company |
| NONE | 0.0 | No match found through any method | Unresolved |
When presenting match results to the user or writing them to CRM records, always include the confidence tier and match method. Downstream commands use the confidence score to decide how aggressively to act: EXACT and HIGH matches proceed automatically, MEDIUM matches proceed with a note, LOW matches require user confirmation.
Return one match result object per participant:
{
client_name: string, // Company name from CRM, or null if unmatched
company_id: string, // Notion page ID for the Company, or null
contact_name: string | null, // Contact name if resolved, null otherwise
contact_id: string | null, // Notion page ID for the Contact, or null
match_confidence: "exact" | "high" | "medium" | "low" | "none",
confidence_score: 0.0-1.0, // Numeric confidence
match_method: string, // Human-readable description of how the match was made
source_email: string | null, // Original email address that was matched
source_name: string | null // Original display name or attendee name
}
When matching multiple participants (e.g., all attendees of a meeting or all recipients of an email), return an array of match results. Group results by company when presenting to the user: show all matched contacts under their parent company.
When processing multiple participants in a single command invocation:
When a domain matches a company but multiple contacts exist at that company:
Some companies operate under multiple domains (e.g., company.com and company.io, or brand.com and parent-corp.com).
When processing a forwarded email, identify the original sender. Look for "Forwarded message" or "---------- Forwarded message ----------" markers. Extract the original From: address and match against that address, not the forwarder's address.
Match CC recipients the same as primary recipients. BCC recipients are not visible in received emails -- do not attempt to match them. When syncing sent emails, the user's own email address appears as the sender -- skip matching the user's own address.
Some calendar events list attendees by name only (no email address). In this case, skip directly to Step 4 (fuzzy name matching). Set a maximum confidence of LOW (0.4) for name-only matches from calendar events.
Skip matching the user's own email address(es). Detect the user's address from the Gmail account or from Notion CRM "My Company" records. The user's email should never appear as a matched client.
Skip any participant with an empty email field, an email missing the @ symbol, or an obviously invalid format. Log: "Skipped malformed email: [value]." Do not count these as unmatched -- they are invalid input.
For detailed personal email domain lists, distribution list patterns, domain normalization rules, and fuzzy name matching specifications, consult ${CLAUDE_PLUGIN_ROOT}/skills/crm/client-matching/references/matching-patterns.md.