hubspot-cli
v0.1.4
Published
CLI and MCP server for the HubSpot CRM API — contacts, companies, deals, tickets, pipelines, and more
Downloads
440
Maintainers
Readme
HubSpot CLI
JSON-first, agent-native CLI for the HubSpot CRM API.
HubSpot has an official CLI (
@hubspot/cli) — but it only covers CMS developer tools (Design Manager, serverless functions, HubDB). There is no official CLI for the CRM API: contacts, companies, deals, tickets, pipelines, owners, engagements, or associations.This CLI fills that gap. Every command returns structured JSON, works from the terminal and as an MCP tool — so your AI agents can manage your entire HubSpot CRM the same way a human would from the command line.
Why Agent-Native?
| | @hubspot/cli (Official) | hubspot-cli (This) |
|---|---|---|
| Scope | CMS only (themes, modules, serverless) | Full CRM API — 55 commands across 11 groups |
| Output | Human-readable text | JSON-first — machine-parseable by default |
| MCP Support | No | Built-in MCP server — every command is an MCP tool |
| Agent Use | Not designed for agents | Every command works identically from terminal or MCP |
| Auth | OAuth / Personal Access Key | Private App access token (3-tier resolution) |
Agent-native means:
- JSON-first output — every response is valid JSON, pipe to
jqor consume from any language - Dual entry point — same commands work as CLI and MCP tools with zero adaptation
- Structured errors — errors return
{ "error": "...", "code": "..." }, not stack traces - Field filtering —
--fields id,properties.emailreturns only what you need - No interactive prompts in automation — all params available as flags, env vars, or config
Install
npm install -g hubspot-cliQuick Start
# 1. Create a Private App access token in HubSpot
# Settings -> Integrations -> Private Apps -> Create a private app
# 2. Authenticate with the token
export HUBSPOT_ACCESS_TOKEN=pat-na1-xxxxx
# List contacts
hubspot contacts list --pretty
# Create a contact
hubspot contacts create --email "[email protected]" --firstname "John" --lastname "Doe"
# Search deals
hubspot deals search --query "acme" --pretty
# Get pipeline stages
hubspot pipelines stages <pipeline-id> --object-type dealsAuth
1. Create a Private App access token
- In HubSpot, go to Settings → Integrations → Private Apps → Create a private app
- In the Basic info tab, give it a name such as
hubspot-cli-agent - In the Scopes tab, add the scopes for the command groups you plan to use:
| Command group | Scopes required |
|---------------|-----------------|
| contacts | crm.objects.contacts.read + crm.objects.contacts.write |
| companies | crm.objects.companies.read + crm.objects.companies.write |
| deals | crm.objects.deals.read + crm.objects.deals.write |
| tickets | tickets |
| owners | crm.objects.owners.read |
| engagements (email read) | sales-email-read only if you need to read email body content |
| lists | crm.lists.read + crm.lists.write |
| properties | crm.schemas.contacts.read + crm.schemas.contacts.write, crm.schemas.companies.read + crm.schemas.companies.write, crm.schemas.deals.read + crm.schemas.deals.write |
- Click Create app
- Open the Auth tab, click Show token, and copy the access token. It starts with
pat-na1-followed by your region.
2. Authenticate
Three-tier resolution (highest priority first):
# Option A: Environment variable (recommended for agents)
export HUBSPOT_ACCESS_TOKEN="pat-na1-xxxxx"
# Option B: Interactive login (saves to ~/.hubspot-cli/config.json)
hubspot login
# Option C: Per-command flag
hubspot contacts list --access-token "pat-na1-xxxxx"3. Verify
hubspot contacts list --limit 1 --prettyCommands
CRM Objects (55 commands)
| Group | Commands |
|-------|----------|
| contacts | list, get, create, update, delete, search, merge |
| companies | list, get, create, update, delete, search |
| deals | list, get, create, update, delete, search |
| tickets | list, get, create, update, delete, search |
| owners | list, get |
| pipelines | list, get, stages |
| engagements | create-note, create-email, create-call, create-task, create-meeting, list, get, delete |
| associations | list, create, delete |
| lists | list, get, create, update, delete, add-members, remove-members, get-members |
| properties | list, get, create, update, delete |
| search | run (universal cross-object search) |
Auth & Config
| Command | Description |
|---------|-------------|
| login | Authenticate with access token |
| logout | Remove stored credentials |
| status | Show current auth + account info |
MCP Server
# Start as MCP server (stdio transport)
hubspot mcpEvery command is registered as an MCP tool. Configure in Claude Desktop, OpenClaw, or any MCP-compatible agent:
{
"mcpServers": {
"hubspot": {
"command": "npx",
"args": ["hubspot-cli", "mcp"],
"env": {
"HUBSPOT_ACCESS_TOKEN": "pat-na1-xxxxx"
}
}
}
}Or with a local install:
{
"mcpServers": {
"hubspot": {
"command": "node",
"args": ["/path/to/hubspot-cli/dist/mcp.js"],
"env": {
"HUBSPOT_ACCESS_TOKEN": "pat-na1-xxxxx"
}
}
}
}Global Options
--access-token <token> Override stored auth
--output <format> json (default) or pretty
--pretty Shorthand for --output pretty
--quiet Suppress output, exit codes only
--fields <fields> Comma-separated field filter (supports nested: properties.email)Examples
# List contacts with specific fields
hubspot contacts list --fields id,properties.email,properties.firstname
# Search companies by name
hubspot companies search --query "acme" --properties name,domain,industry --pretty
# Create a deal in a pipeline stage
hubspot deals create --dealname "Acme Enterprise" --amount "50000" \
--pipeline "<pipeline-id>" --dealstage "<stage-id>"
# Get all deal pipelines with stages
hubspot pipelines list --object-type deals --pretty
# Log a note
hubspot engagements create-note --body "Discovery call — interested in enterprise plan"
# Create a follow-up task
hubspot engagements create-task --subject "Send proposal" --status NOT_STARTED --priority HIGH
# Associate a contact with a company
hubspot associations create --from-type contacts --from-id 123 \
--to-type companies --to-id 456 --type-id 1
# Manage a list
hubspot lists create --name "VIP Customers" --processing-type MANUAL
hubspot lists add-members <list-id> --record-ids "123,456"
# Create a custom property
hubspot properties create --object-type contacts --name "lead_score" \
--label "Lead Score" --type number --field-type number --group contactinformation
# Universal search across any object type
hubspot search run --object-type deals \
--filter '{"filters":[{"propertyName":"amount","operator":"GT","value":"10000"}]}' \
--properties dealname,amount,dealstage
# Pipe to jq
hubspot contacts list | jq '.results[].properties.email'Architecture
This CLI follows the same metadata-driven architecture as instantly-cli (156 commands) and clay-gtm-cli:
- CommandDefinition — single struct drives both CLI registration and MCP tool registration
- Zod schemas — input validation shared between CLI and MCP
- CRM Object Factory —
createCrmObjectCommands()generates CRUD + search for any HubSpot object type - Thin REST client — ~130 lines, cursor-based pagination, exponential backoff on 429s
- Dual entry —
dist/index.js(CLI) anddist/mcp.js(MCP server)
License
MIT
