HubSpot Integration - Team Setup Guide

Last Updated: April 1, 2026
Status: Production Ready

This guide helps Brainforge team members access HubSpot with the right default: use the HubSpot app first, then HubSpot MCP as a read-only fallback in Cursor, and use the API service only for programmatic writes or automation.


Quick Start (5 minutes)

Prerequisites

  • Access to Brainforge 1Password vault
  • Cursor IDE installed
  • Node.js 18+ installed
  • 1Password CLI installed (brew install --cask 1password-cli)

Step 1: Start in the HubSpot app

Use the HubSpot app by default for:

  • Reviewing pipeline state
  • Inspecting deal, company, and contact records
  • Manual CRM edits by humans

Only continue to MCP or API setup if you want Cursor-based lookup or automation.

Step 2: Get Credentials from 1Password

# Sign in to 1Password CLI (first time only)
op signin
 
# Verify you can access the credentials
op read "op://Personal/Hubspot Brainforge Development App/notesPlain" | head -5

1Password Items Required:

ItemVaultPurpose
Hubspot Brainforge Development AppPersonalAPI Service (read/write)
Hubspot MCPPersonalMCP Server (read-only)

Step 3: Set Up the API Service

# Navigate to the API service
cd integrations/hubspot/api-service
 
# Install dependencies
npm install
 
# Create .env file with 1Password token
echo "HUBSPOT_ACCESS_TOKEN=$(op read 'op://Personal/Hubspot Brainforge Development App/credential')" > .env

Step 4: Set Up HubSpot MCP in Cursor

The MCP is a read-only fallback for Cursor. It is already configured globally. After restarting Cursor, it should auto-connect.

To verify MCP is working, ask in Cursor:

"Show me all deals for Inteleos"

What You Can Do

HubSpot app (default)

The HubSpot app should be the team’s primary access path:

  • Open records directly in HubSpot for the current source of truth
  • Use the UI for ordinary human review and edits
  • Validate pipeline status there before using CRM values in delivery planning

Natural Language Queries (via MCP fallback - Read Only)

The HubSpot MCP allows you to query HubSpot data using natural language in Cursor when the app is inconvenient or the user wants in-chat retrieval:

"Show me all deals for [company name]"
"Get contact details for [person name]"
"What deals are in the proposal stage?"
"Who are the contacts at [company]?"

Programmatic Operations (via API Service - Read/Write)

The API service is for deliberate automation and agent-driven writes:

import { 
  // Companies
  getCompany, getCompanyByName, getCompanyByDomain, searchCompanies,
  // Contacts  
  getContact, getContactByEmail, getContactByName, searchContacts,
  // Deals
  getDeal, searchDeals, updateDeal, updateDealStage, createDeal, addNoteToDeal,
  // Associations
  getDealWithAssociations, traverseDealAssociations,
  associateContactToDeal, associateCompanyToDeal,
} from './src/index.js';
 
// Example: Update a deal stage
await updateDealStage('262356318908', '1103130706'); // Move to "Complete: Won"
 
// Example: Get full context for a deal
const context = await traverseDealAssociations('262356318908');
console.log(context.deal, context.contacts, context.company);

API Reference

Deal Stages (Default Pipeline)

Stage IDLabel
appointmentscheduledTo do: Research/Pre-Qualification
qualifiedtobuyTo do: Circle Back
presentationscheduledTo do: Lead
938739088In Progress: Qualification Call
decisionmakerboughtinIn Progress: Discovery Call
1103130701In Progress: Demo
1103130702In Progress: Proposal Creation
1103130703In Progress: Proposal in Review
1985819336In Progress: Verbal Commit
1103130705In Progress: Signing
1103130706Complete: Won

Available Functions

Companies

FunctionDescription
getCompany(id)Get company by HubSpot ID
getCompanyByName(name)Find company by exact name
getCompanyByDomain(domain)Find company by domain
searchCompanies(query, limit)Search companies

Contacts

FunctionDescription
getContact(id)Get contact by HubSpot ID
getContactByEmail(email)Find contact by email
getContactByName(first, last)Find contacts by name
searchContacts(query, limit)Search contacts

Deals

FunctionDescription
getDeal(id)Get deal by HubSpot ID
createDeal(properties)Create a new deal
updateDeal(id, properties)Update deal properties
updateDealStage(id, stage)Change deal stage
searchDeals(query, limit)Search deals
addNoteToDeal(id, note)Add a note to a deal

Associations

FunctionDescription
getDealAssociations(dealId)Get contacts and company for a deal
getDealWithAssociations(dealId)Get deal with all associations
traverseDealAssociations(dealId)Full context tree traversal
associateContactToDeal(dealId, contactId)Link contact to deal
associateCompanyToDeal(dealId, companyId)Link company to deal

Troubleshooting

”HUBSPOT_ACCESS_TOKEN environment variable is required"

# Make sure .env exists and has the token
cat api-service/.env
 
# If missing, recreate it:
echo "HUBSPOT_ACCESS_TOKEN=$(op read 'op://Personal/Hubspot Brainforge Development App/credential')" > api-service/.env

"1Password CLI not signed in"

op signin

"MCP not responding in Cursor”

  1. Restart Cursor completely
  2. Check MCP status in Cursor settings
  3. Re-authorize if prompted
  4. If you only need to inspect data, use the HubSpot app instead of blocking on MCP

”Rate limit exceeded”

The API service has built-in rate limiting (9 req/sec). If you hit limits:

  • Wait 10 seconds and retry
  • The client auto-retries on 429 errors (up to 3 times)

“Company/Contact not found”

Search functions require exact matches. Try:

  • Using searchCompanies() or searchContacts() with partial names
  • Checking for typos in names/emails

Architecture

┌─────────────────────────────────────────────────────────────┐
│                     Cursor IDE                               │
├─────────────────────────────────────────────────────────────┤
│                                                              │
│  ┌─────────────────────┐    ┌─────────────────────────────┐ │
│  │   HubSpot MCP       │    │   HubSpot API Service       │ │
│  │   (Read Only)       │    │   (Read/Write)              │ │
│  │                     │    │                             │ │
│  │ - Natural language  │    │ - CRUD operations           │ │
│  │ - Query deals       │    │ - Update deal stages        │ │
│  │ - Search contacts   │    │ - Add notes                 │ │
│  │ - Get properties    │    │ - Create associations       │ │
│  └─────────────────────┘    └─────────────────────────────┘ │
│           │                            │                     │
└───────────┼────────────────────────────┼─────────────────────┘
            │                            │
            ▼                            ▼
     ┌─────────────────────────────────────────┐
     │           HubSpot CRM API               │
     │                                         │
     │  Contacts | Companies | Deals | Notes   │
     └─────────────────────────────────────────┘

Files Overview

integrations/hubspot/
├── api-service/
│   ├── src/
│   │   ├── index.ts          # Main exports
│   │   ├── client.ts         # HubSpot client factory
│   │   ├── companies.ts      # Company operations
│   │   ├── contacts.ts       # Contact operations
│   │   ├── deals.ts          # Deal operations
│   │   └── associations.ts   # Association traversal
│   └── .env                  # Your local credentials
├── enrichment/               # Linear ticket enrichment
├── TEAM_SETUP.md             # This file
├── CREDENTIALS.md            # Credential management details
├── README.md                 # Overview and architecture
└── QUICK_START_CURSOR.md     # MCP quick start

Support

  • 1Password Issues: Contact team admin for vault access
  • HubSpot Access: Request access through HubSpot admin
  • API Questions: Check this guide or ask in engineering Slack

Changelog

DateChange
2026-04-01Reframed access guidance: HubSpot app first, MCP fallback, API for automation
2026-01-31Fixed API: filterGroups for search, v4 associations API
2026-01-16Initial integration