Import Contacts

by HubSpota0c59600fc1dNo licenseListed Oct 8, 2026Updated Oct 8, 2026

Imports contacts into HubSpot from any source — a CSV file, a pasted list, or data from connected apps like Gmail. Handles field mapping, duplicate detection, batch import, and company association. ALWAYS use this skill when the user wants to bring contacts into HubSpot — "import contacts", "upload a CSV", "add these people to HubSpot", "import my list", "bring in contacts from [source]", "I have a spreadsheet of contacts", "add contacts from my email", "migrate contacts", "sync contacts from [app]", "load my network". Trigger whenever the user wants to bulk-add people to the CRM, regardless of source.

Instructions only

Import Contacts

Tool names below are expected names for the HubSpot MCP connector. If a named tool isn't available, check for updates to the skill and/or alternates in the HubSpot toolset as available tools may change


Phase 1 — Identify the data source

Use this priority order:

  1. Infer from context — if the user attached a file, said "from my CSV", "from Salesforce", or similar, proceed directly to Phase 2 with that source.
  2. Check connected services — silently test which connectors are available (attempt a lightweight tool call for each). Build a dynamic list of sources to offer.
  3. Ask if the source isn't clear.

Ask as plain text — no widget. Build the question based on what connectors are available:

If connected services are detected, list them under a heading, then offer the manual options:

Where are your contacts coming from?
From a connected service:1. [Email provider] — extract contacts from recent threads2. [Other CRM, e.g. Salesforce] — pull contacts from existing records
Or add them manually:3. Upload a file — share a path or attach a CSV/spreadsheet4. Paste a list — names, emails, and companies

If no connectors are detected:

Where are your contacts coming from?1. Upload a file — share a path or attach a CSV/spreadsheet2. Paste a list — names, emails, and companies

For connected email provider: Use the connector's search/thread tools to find recent contacts. Extract unique senders and recipients from recent threads. Record the timestamp of the most recent thread per contact as the "last contact" date.

For connected CRM: Use the CRM's export or search tools to pull contact records. Map the source CRM's fields to HubSpot properties.

Fetch portal context early using get_organization_details and get_user_details. Store portalId, userId (for hubspot_owner_id), and the user's email domain (for filtering internal colleagues in Phase 2).


Phase 2 — Parse, deduplicate, and confirm

Field mapping

Map detected column headers (or inferred positions) to HubSpot contact properties:

Detected columnHubSpot property
name, full nameSplit into firstname + lastname
first / first namefirstname
last / last name / surnamelastname
email, email addressemail
phone, mobile, cellphone
company, organizationcompany
title, job title, rolejobtitle
website, urlwebsite
linkedinhs_linkedin_url

Use get_properties with objectType: contacts to confirm target properties exist. Use search_properties for non-standard or custom column names.

Filter internal contacts

Remove any contact whose email domain matches the user's own domain from Phase 1. Contacts with no email cannot be filtered on domain — leave them in; a warning will surface in the widget. Note how many were removed — surface this in the widget header.

Duplicate check

For contacts with a valid email, batch into groups of 50 and call search_crm_objects:

  • objectType: contacts
  • filter: email IN [...batch of emails...]
  • properties: email, firstname, lastname, hs_object_id

Classify each contact as New (not in HubSpot) or Existing (already in HubSpot).

Data quality flags

Before showing the widget, flag:

  • Rows with no email address
  • Malformed email addresses
  • Duplicate emails within the source file itself
  • Unmapped columns

Contact selection widget

Render an interactive widget using show_widget. Do not show a text summary first — the widget is the confirmation step.

The widget must include:

  1. Header: source label (e.g. "Found in your CSV"), subtitle with source metadata, and a note if contacts were skipped (internal domain, invalid emails)
  2. Scrollable table with columns: checkbox, NAME, EMAIL, COMPANY, LAST CONTACT (for email/CRM source; omit for CSV/paste), STATUS badge ("Already in HubSpot" for existing contacts)
  3. Select-all checkbox in the header row — toggles all, shows indeterminate state if partial
  4. Footer: "Cancel" text button and a primary "Import N contacts" button (N updates live as checkboxes are toggled; disabled if 0 selected)

On "Import N contacts" click:

js
sendPrompt('IMPORT_CONFIRMED:' + JSON.stringify(selectedEmails))

On "Cancel":

js
sendPrompt('IMPORT_CANCELLED')

Include all contacts in the widget regardless of duplicate status. Contacts with no email or invalid email: include but unchecked by default with a muted "No email" label. Existing contacts: include, checked by default, with the status badge.

Handling responses:

  • IMPORT_CONFIRMED:[...] — parse the JSON array and proceed to Phase 3
  • IMPORT_CANCELLED — acknowledge and stop
  • Free-text message (e.g. "skip the ones from Acme") — interpret, adjust selection, re-render widget

Do not proceed to Phase 3 until a confirmed selection is received.


Phase 3 — Import

Prepare records

For each confirmed contact:

  1. Build HubSpot properties object from the confirmed field mapping
  2. Split full names: everything before the first space = firstname, everything after = lastname. Single-word names → firstname only, lastname blank. If firstname/lastname columns exist separately, use them directly instead of splitting.
  3. Assign hubspot_owner_id to the current user's ID from Phase 1
  4. Note any company name for association

Batch import

Split into batches of 50. For each batch, call manage_crm_objects:

  • New contacts: createRequest, objectType: contacts
  • Updates: updateRequest, objectType: contacts, using hs_object_id from Phase 2

Show a single updating progress line:

Importing 55 contacts… (batch 3 of 6 complete)

Capture any per-record errors and store for the Phase 4 summary.

Company association

For contacts with a company name:

  1. search_crm_objects companies, filter: name = [company name]
  2. If found, associate via manage_crm_objects with association type contact_to_company
  3. If not found, create via manage_crm_objects createRequest, objectType: companies, then associate

Batch company lookups where possible to reduce API calls.


Phase 4 — Summary

Import complete.
  ✓ [N] contacts created  ✓ [N] contacts updated  — [N] contacts skipped (no email) — [names up to 3, +N more]  ✗ [N] errors (see below)
Errors:  Row [N]: "[value]" — [reason]
Companies:  · [N] new companies created  · [N] contacts associated with existing companies
View contacts: https://[uiDomain]/contacts/[portalId]/contacts/list/view/all/

Name individual skipped/errored contacts up to 5; after that "[first 5 names] + N more." If any rows errored, offer to export a list so the user can fix and re-import.


Phase 5 — Post-import: log history and surface deal signals

Run after Phase 4. Only apply the steps relevant to the import source.

5a — Log existing communication history (email/CRM sources only)

If contacts were sourced from a connected email provider or CRM:

  1. For each newly imported contact, search the source connector for recent threads or interactions involving their email address (last 90 days, up to 5 per contact).
  2. For each thread found, create a note in HubSpot:
    • manage_crm_objects notes, createRequest: hs_note_body: "[Date] — [Subject/topic] via [source]", hs_timestamp: thread date, association: contact
  3. Skip contacts where no threads are found — no note needed.
  4. Cap total notes written to 100 (prioritise most recent threads first if over the limit).

5b — Detect deal signals

Review the threads or records from 5a (or the source data itself if CSV/paste) for buying signals: pricing discussions, demo requests, proposal mentions, evaluation timelines, or decision language.

For contacts with a clear signal:

  • Suggest creating a deal: "I noticed [Name] mentioned [signal]. Want me to create a deal for them?"
  • If the user confirms, create via manage_crm_objects deals, createRequest: dealname: "[Contact Name] — [company]", dealstage: appointmentscheduled, associations: contact → contactId.
  • If there are multiple signal contacts, show a brief table (Name, Signal, Company) and ask which to convert.

Skip contacts with no signals — don't create speculative deals.

5c — Recommend ongoing activity logging

After a successful import, prompt:

"To keep [N] new contacts up to date automatically, connect your email to HubSpot. That way future emails are logged as activity without any manual steps. Say 'connect my email to HubSpot' when you're ready to set it up."

Skip this prompt if an email connector is already logging to HubSpot (infer from whether 5a returned activity data).


Edge cases

  • No email column: warn strongly — HubSpot deduplicates by email. Offer to continue with a caveat or ask the user to add emails first.
  • Large files (>500 rows): warn that import may take a moment. Continue without extra confirmation.
  • All contacts are duplicates: confirm with the user before exiting — they may have intended to update records.
  • Source returns no contacts: let the user know and suggest they try a different source or add contacts manually.
  • Company association fails: log the failure in the summary but do not block the contact import.

Source and attribution

Source:HubSpot/hubspot-mcp-pluginsinHubSpot-Sales/skills/import-contactsat commita0c5960

License: No license

Content belongs to its original authors. SourceWeft indexes it from a public repository.

Report or request removal

More from HubSpot/hubspot-mcp-plugins

Pipeline Pulse

HubSpot

Summarizes open HubSpot deals by stage, flags stalled or overdue ones, and proposes follow-up tasks.

Business & FinanceOct 8, 2026

Onboarding

HubSpot

Guides a new HubSpot user through portal setup, goal capture, and tailored next steps.

Productivity & WorkflowOct 8, 2026

Log Call

HubSpot

Logs a completed call or meeting to HubSpot: writes a note, updates deal and contact fields, and creates a follow-up task.

Productivity & WorkflowOct 8, 2026

Hubspot

HubSpot

HubSpot CRM assistant that answers lookups, stats and quick updates, and routes to specialized CRM skills.

Productivity & WorkflowOct 8, 2026

Follow Up

HubSpot

Drafts a personalised follow-up or outreach email for a named contact, grounded in HubSpot deal context, recent notes, and email history. Opens HubSpot with the email pre-populated so the rep can review and send with full tracking. If deal-related, updates the next step or deal stage as applicable. ALWAYS use this skill when the user wants to write or send outbound communication to a specific contact — "follow up with X", "draft an email to X", "send something to X", "check in with X", "reach out to X", "ping X", "touch base with X", "I need to reply to X", "draft a follow-up for [deal]", "write to X". Trigger on any request to compose outbound communication tied to a contact or deal.

Awaiting classificationOct 8, 2026

Daily Brief

HubSpot

Builds a prioritised daily brief from HubSpot CRM data and connected apps, suggesting GTM tasks without creating them.

Productivity & WorkflowOct 8, 2026