HubSpot MCP Tools & API Patterns
Overview
HubSpot provides a first-party remote MCP server at https://mcp.hubspot.com/ for AI tool integration. The MCP server uses OAuth 2.0 with PKCE for authentication and Streamable HTTP as its transport protocol. Tools are backed by the HubSpot CRM Search API and cover contacts, companies, deals, tickets, tasks, notes, and associations. This skill covers MCP server connection, the complete tool reference, search patterns, error handling, and best practices.
Anti-triggers
- What properties an object has and what its enum values mean — the field,
lifecycle-stage, and pipeline tables live with the object; use
hubspot-contacts, hubspot-companies, hubspot-deals, or
hubspot-tickets.
- A different hosted OAuth MCP server — the connection shape rhymes but
the tenant, scopes, session model, and tools do not; use
warmly-api-patterns or pandadoc-api-patterns.
Connection & Authentication
MCP Server
HubSpot hosts an official remote MCP server. Authentication uses OAuth 2.0 with PKCE, handled by the mcp-remote bridge:
- Go to developers.hubspot.com
- Navigate to Development > MCP Auth Apps
- Create a new MCP Auth App
- Copy the Client ID and Client Secret
MCP Server URL: https://mcp.hubspot.com/
Transport: Streamable HTTP
Authentication: OAuth 2.0 + PKCE (handled automatically by mcp-remote)
Environment Variables
export HUBSPOT_CLIENT_ID="your-client-id"
export HUBSPOT_CLIENT_SECRET="your-client-secret"
Claude Desktop Configuration
{
"mcpServers": {
"hubspot": {
"command": "npx",
"args": [
"-y", "mcp-remote",
"https://mcp.hubspot.com/"
],
"env": {
"HUBSPOT_CLIENT_ID": "YOUR_CLIENT_ID",
"HUBSPOT_CLIENT_SECRET": "YOUR_CLIENT_SECRET"
}
}
}
}
Scopes
HubSpot MCP automatically derives required OAuth scopes from the tools you use. You do not need to manually configure scopes. For example:
- Using contact tools automatically requests
crm.objects.contacts.read and crm.objects.contacts.write
- Using deal tools automatically requests
crm.objects.deals.read and crm.objects.deals.write
- Using association tools automatically requests the appropriate association scopes
Sensitive Data
HubSpot MCP excludes sensitive data properties (PHI -- Protected Health Information) from tool responses by default. Properties marked as sensitive in HubSpot settings will not appear in MCP tool results.
Complete MCP Tool Reference
Contact Tools
| Tool |
Description |
Key Parameters |
hubspot_retrieve_contact |
Get a single contact by ID |
contactId (required) |
hubspot_create_contact |
Create a new contact |
email (required), firstname, lastname, phone, company |
hubspot_update_contact |
Update an existing contact |
contactId (required), property fields to update |
hubspot_list_contacts |
List contacts with pagination |
limit, after (cursor) |
hubspot_list_contact_properties |
List all contact properties |
None |
hubspot_search_contacts |
Search contacts by criteria |
filterGroups, sorts, limit, after |
Company Tools
| Tool |
Description |
Key Parameters |
hubspot_retrieve_company |
Get a single company by ID |
companyId (required) |
hubspot_create_company |
Create a new company |
name (required), domain, industry, phone |
hubspot_update_company |
Update an existing company |
companyId (required), property fields to update |
hubspot_list_company_properties |
List all company properties |
None |
hubspot_search_companies |
Search companies by criteria |
filterGroups, sorts, limit, after |
Deal Tools
| Tool |
Description |
Key Parameters |
hubspot_retrieve_deal |
Get a single deal by ID |
dealId (required) |
hubspot_create_deal |
Create a new deal |
dealname (required), amount, dealstage, pipeline |
hubspot_update_deal |
Update an existing deal |
dealId (required), property fields to update |
hubspot_list_deal_properties |
List all deal properties |
None |
hubspot_search_deals |
Search deals by criteria |
filterGroups, sorts, limit, after |
Ticket Tools
| Tool |
Description |
Key Parameters |
hubspot_retrieve_ticket |
Get a single ticket by ID |
ticketId (required) |
hubspot_create_ticket |
Create a new ticket |
subject (required), content, hs_pipeline, hs_pipeline_stage |
hubspot_update_ticket |
Update an existing ticket |
ticketId (required), property fields to update |
Activity Tools
| Tool |
Description |
Key Parameters |
hubspot_create_task |
Create a task |
hs_task_subject (required), hs_task_body, hs_task_priority, hs_timestamp |
hubspot_create_note |
Create a note |
hs_note_body (required), hs_timestamp |
Utility Tools
| Tool |
Description |
Key Parameters |
hubspot_open_hubspot_ui |
Open HubSpot UI for an object |
objectType, objectId |
hubspot_get_user_details |
Get details of the current user |
None |
Association Tools
| Tool |
Description |
Key Parameters |
hubspot_create_association |
Create an association between objects |
fromObjectType, fromObjectId, toObjectType, toObjectId, associationType |
hubspot_access_associations |
List associations for an object |
objectType, objectId, toObjectType |
CRM Search API
Search Patterns
HubSpot MCP tools that search records use the CRM Search API under the hood. Search tools accept filterGroups for structured queries:
Filter Group Structure:
{
"filterGroups": [
{
"filters": [
{
"propertyName": "email",
"operator": "CONTAINS_TOKEN",
"value": "acme.com"
}
]
}
]
}
Available Operators
| Operator |
Description |
Example |
EQ |
Equals |
{"propertyName": "lifecyclestage", "operator": "EQ", "value": "customer"} |
NEQ |
Not equals |
{"propertyName": "lifecyclestage", "operator": "NEQ", "value": "subscriber"} |
LT |
Less than |
{"propertyName": "amount", "operator": "LT", "value": "1000"} |
LTE |
Less than or equal |
{"propertyName": "amount", "operator": "LTE", "value": "5000"} |
GT |
Greater than |
{"propertyName": "amount", "operator": "GT", "value": "10000"} |
GTE |
Greater than or equal |
{"propertyName": "createdate", "operator": "GTE", "value": "2026-01-01"} |
CONTAINS_TOKEN |
Contains token (word match) |
{"propertyName": "email", "operator": "CONTAINS_TOKEN", "value": "acme"} |
NOT_CONTAINS_TOKEN |
Does not contain token |
{"propertyName": "email", "operator": "NOT_CONTAINS_TOKEN", "value": "test"} |
HAS_PROPERTY |
Property has a value |
{"propertyName": "phone", "operator": "HAS_PROPERTY"} |
NOT_HAS_PROPERTY |
Property has no value |
{"propertyName": "phone", "operator": "NOT_HAS_PROPERTY"} |
IN |
Value in list |
{"propertyName": "dealstage", "operator": "IN", "values": ["stage1", "stage2"]} |
NOT_IN |
Value not in list |
{"propertyName": "dealstage", "operator": "NOT_IN", "values": ["closedlost"]} |
BETWEEN |
Between two values |
{"propertyName": "amount", "operator": "BETWEEN", "value": "1000", "highValue": "5000"} |
Sorting
{
"sorts": [
{
"propertyName": "createdate",
"direction": "DESCENDING"
}
]
}
Sort Directions: ASCENDING, DESCENDING
Pagination
Search results use cursor-based pagination:
| Parameter |
Description |
Default |
Max |
limit |
Results per page |
10 |
100 |
after |
Cursor for next page |
None |
- |
Iterating through all results:
- Call the search tool with
limit=100
- Check the response for a
paging.next.after value
- If present, call again with
after set to that value
- Repeat until no
paging.next.after is returned
Response Format
Single Resource:
{
"id": "12345",
"properties": {
"firstname": "John",
"lastname": "Smith",
"email": "john.smith@acmecorp.com",
"company": "Acme Corporation",
"phone": "555-123-4567",
"lifecyclestage": "customer",
"createdate": "2025-06-15T10:30:00.000Z",
"lastmodifieddate": "2026-01-20T14:15:00.000Z"
},
"createdAt": "2025-06-15T10:30:00.000Z",
"updatedAt": "2026-01-20T14:15:00.000Z"
}
Search Results:
{
"total": 47,
"results": [
{
"id": "12345",
"properties": {
"firstname": "John",
"lastname": "Smith",
"email": "john.smith@acmecorp.com"
}
}
],
"paging": {
"next": {
"after": "12345"
}
}
}
Rate Limiting
Rate Limit Details
| Metric |
Limit |
| Requests per 10 seconds |
100 (per OAuth app) |
| Requests per day |
500,000 (varies by plan) |
| Search requests per day |
1,000 (Free), 10,000+ (paid plans) |
When rate limited, the MCP tool will return a 429 error. Wait before retrying. The MCP server handles OAuth token refresh automatically.
Plan-Based Limits
| HubSpot Plan |
Daily API Limit |
Search Limit |
| Free |
100,000 |
1,000 |
| Starter |
250,000 |
5,000 |
| Professional |
500,000 |
10,000 |
| Enterprise |
1,000,000 |
25,000 |
Error Handling
Common Errors
| Error |
Cause |
Resolution |
| Tool not found |
MCP server not connected |
Verify OAuth credentials and server URL |
| 401 Unauthorized |
OAuth token expired or invalid |
Restart MCP connection to re-authenticate |
| 403 Forbidden |
Insufficient scopes or plan limitation |
Check HubSpot plan tier and MCP Auth App permissions |
| 404 Not Found |
Invalid object ID |
Verify the record ID exists |
| 409 Conflict |
Duplicate record |
Check for existing records before creating |
| 429 Too Many Requests |
Rate limit exceeded |
Wait 10 seconds and retry |
| Invalid property |
Property name not valid |
Use list_*_properties tools to check available properties |
Troubleshooting MCP Connection
- Verify credentials - Ensure
HUBSPOT_CLIENT_ID and HUBSPOT_CLIENT_SECRET are correct
- Check URL - MCP server URL must be
https://mcp.hubspot.com/
- Test with a simple call - Try
hubspot_get_user_details to verify connectivity
- Re-authenticate - Restart the MCP connection to force a fresh OAuth flow
- Check plan - Ensure your HubSpot plan supports the API features you need
Best Practices
- Filter server-side - Use
hubspot_search_* tools with filterGroups instead of listing all records
- Use maximum page size - Set
limit=100 to minimize total tool calls
- Monitor rate limits - Stay well under 100 requests per 10 seconds
- Use associations - Link related objects (contacts to companies, deals to contacts) for full context
- Check properties first - Use
list_*_properties tools to discover available fields before searching
- Validate before creating - Search for existing records before creating duplicates
- Use lifecycle stages - Track contacts and companies through their lifecycle for accurate reporting
- Cache property lists - Property definitions change infrequently; reference them across multiple operations
Related Skills
1---2name: hubspot-api-patterns3description: HubSpot's official remote MCP server and the CRM Search API behind it: the complete MCP tool catalog, OAuth 2.0 + PKCE connection over Streamable HTTP, automatic scope derivation, sensitive-data (PHI) exclusion, filter/sort/ pagination syntax, plan-tier rate limits, and error handling.4---56# HubSpot MCP Tools & API Patterns78## Overview910HubSpot provides a first-party remote MCP server at `https://mcp.hubspot.com/` for AI tool integration. The MCP server uses OAuth 2.0 with PKCE for authentication and Streamable HTTP as its transport protocol. Tools are backed by the HubSpot CRM Search API and cover contacts, companies, deals, tickets, tasks, notes, and associations. This skill covers MCP server connection, the complete tool reference, search patterns, error handling, and best practices.1112## Anti-triggers1314- **What properties an object has and what its enum values mean** — the field,15 lifecycle-stage, and pipeline tables live with the object; use16 `hubspot-contacts`, `hubspot-companies`, `hubspot-deals`, or17 `hubspot-tickets`.18- **A different hosted OAuth MCP server** — the connection shape rhymes but19 the tenant, scopes, session model, and tools do not; use20 `warmly-api-patterns` or `pandadoc-api-patterns`.2122## Connection & Authentication2324### MCP Server2526HubSpot hosts an official remote MCP server. Authentication uses OAuth 2.0 with PKCE, handled by the `mcp-remote` bridge:27281. Go to [developers.hubspot.com](https://developers.hubspot.com)292. Navigate to **Development > MCP Auth Apps**303. Create a new MCP Auth App314. Copy the **Client ID** and **Client Secret**3233**MCP Server URL:** `https://mcp.hubspot.com/`3435**Transport:** Streamable HTTP3637**Authentication:** OAuth 2.0 + PKCE (handled automatically by `mcp-remote`)3839### Environment Variables4041```bash42export HUBSPOT_CLIENT_ID="your-client-id"43export HUBSPOT_CLIENT_SECRET="your-client-secret"44```4546### Claude Desktop Configuration4748```json49{50 "mcpServers": {51 "hubspot": {52 "command": "npx",53 "args": [54 "-y", "mcp-remote",55 "https://mcp.hubspot.com/"56 ],57 "env": {58 "HUBSPOT_CLIENT_ID": "YOUR_CLIENT_ID",59 "HUBSPOT_CLIENT_SECRET": "YOUR_CLIENT_SECRET"60 }61 }62 }63}64```6566### Scopes6768HubSpot MCP automatically derives required OAuth scopes from the tools you use. You do not need to manually configure scopes. For example:6970- Using contact tools automatically requests `crm.objects.contacts.read` and `crm.objects.contacts.write`71- Using deal tools automatically requests `crm.objects.deals.read` and `crm.objects.deals.write`72- Using association tools automatically requests the appropriate association scopes7374### Sensitive Data7576HubSpot MCP excludes sensitive data properties (PHI -- Protected Health Information) from tool responses by default. Properties marked as sensitive in HubSpot settings will not appear in MCP tool results.7778## Complete MCP Tool Reference7980### Contact Tools8182| Tool | Description | Key Parameters |83|------|-------------|----------------|84| `hubspot_retrieve_contact` | Get a single contact by ID | `contactId` (required) |85| `hubspot_create_contact` | Create a new contact | `email` (required), `firstname`, `lastname`, `phone`, `company` |86| `hubspot_update_contact` | Update an existing contact | `contactId` (required), property fields to update |87| `hubspot_list_contacts` | List contacts with pagination | `limit`, `after` (cursor) |88| `hubspot_list_contact_properties` | List all contact properties | None |89| `hubspot_search_contacts` | Search contacts by criteria | `filterGroups`, `sorts`, `limit`, `after` |9091### Company Tools9293| Tool | Description | Key Parameters |94|------|-------------|----------------|95| `hubspot_retrieve_company` | Get a single company by ID | `companyId` (required) |96| `hubspot_create_company` | Create a new company | `name` (required), `domain`, `industry`, `phone` |97| `hubspot_update_company` | Update an existing company | `companyId` (required), property fields to update |98| `hubspot_list_company_properties` | List all company properties | None |99| `hubspot_search_companies` | Search companies by criteria | `filterGroups`, `sorts`, `limit`, `after` |100101### Deal Tools102103| Tool | Description | Key Parameters |104|------|-------------|----------------|105| `hubspot_retrieve_deal` | Get a single deal by ID | `dealId` (required) |106| `hubspot_create_deal` | Create a new deal | `dealname` (required), `amount`, `dealstage`, `pipeline` |107| `hubspot_update_deal` | Update an existing deal | `dealId` (required), property fields to update |108| `hubspot_list_deal_properties` | List all deal properties | None |109| `hubspot_search_deals` | Search deals by criteria | `filterGroups`, `sorts`, `limit`, `after` |110111### Ticket Tools112113| Tool | Description | Key Parameters |114|------|-------------|----------------|115| `hubspot_retrieve_ticket` | Get a single ticket by ID | `ticketId` (required) |116| `hubspot_create_ticket` | Create a new ticket | `subject` (required), `content`, `hs_pipeline`, `hs_pipeline_stage` |117| `hubspot_update_ticket` | Update an existing ticket | `ticketId` (required), property fields to update |118119### Activity Tools120121| Tool | Description | Key Parameters |122|------|-------------|----------------|123| `hubspot_create_task` | Create a task | `hs_task_subject` (required), `hs_task_body`, `hs_task_priority`, `hs_timestamp` |124| `hubspot_create_note` | Create a note | `hs_note_body` (required), `hs_timestamp` |125126### Utility Tools127128| Tool | Description | Key Parameters |129|------|-------------|----------------|130| `hubspot_open_hubspot_ui` | Open HubSpot UI for an object | `objectType`, `objectId` |131| `hubspot_get_user_details` | Get details of the current user | None |132133### Association Tools134135| Tool | Description | Key Parameters |136|------|-------------|----------------|137| `hubspot_create_association` | Create an association between objects | `fromObjectType`, `fromObjectId`, `toObjectType`, `toObjectId`, `associationType` |138| `hubspot_access_associations` | List associations for an object | `objectType`, `objectId`, `toObjectType` |139140## CRM Search API141142### Search Patterns143144HubSpot MCP tools that search records use the CRM Search API under the hood. Search tools accept `filterGroups` for structured queries:145146**Filter Group Structure:**147148```json149{150 "filterGroups": [151 {152 "filters": [153 {154 "propertyName": "email",155 "operator": "CONTAINS_TOKEN",156 "value": "acme.com"157 }158 ]159 }160 ]161}162```163164### Available Operators165166| Operator | Description | Example |167|----------|-------------|---------|168| `EQ` | Equals | `{"propertyName": "lifecyclestage", "operator": "EQ", "value": "customer"}` |169| `NEQ` | Not equals | `{"propertyName": "lifecyclestage", "operator": "NEQ", "value": "subscriber"}` |170| `LT` | Less than | `{"propertyName": "amount", "operator": "LT", "value": "1000"}` |171| `LTE` | Less than or equal | `{"propertyName": "amount", "operator": "LTE", "value": "5000"}` |172| `GT` | Greater than | `{"propertyName": "amount", "operator": "GT", "value": "10000"}` |173| `GTE` | Greater than or equal | `{"propertyName": "createdate", "operator": "GTE", "value": "2026-01-01"}` |174| `CONTAINS_TOKEN` | Contains token (word match) | `{"propertyName": "email", "operator": "CONTAINS_TOKEN", "value": "acme"}` |175| `NOT_CONTAINS_TOKEN` | Does not contain token | `{"propertyName": "email", "operator": "NOT_CONTAINS_TOKEN", "value": "test"}` |176| `HAS_PROPERTY` | Property has a value | `{"propertyName": "phone", "operator": "HAS_PROPERTY"}` |177| `NOT_HAS_PROPERTY` | Property has no value | `{"propertyName": "phone", "operator": "NOT_HAS_PROPERTY"}` |178| `IN` | Value in list | `{"propertyName": "dealstage", "operator": "IN", "values": ["stage1", "stage2"]}` |179| `NOT_IN` | Value not in list | `{"propertyName": "dealstage", "operator": "NOT_IN", "values": ["closedlost"]}` |180| `BETWEEN` | Between two values | `{"propertyName": "amount", "operator": "BETWEEN", "value": "1000", "highValue": "5000"}` |181182### Sorting183184```json185{186 "sorts": [187 {188 "propertyName": "createdate",189 "direction": "DESCENDING"190 }191 ]192}193```194195**Sort Directions:** `ASCENDING`, `DESCENDING`196197### Pagination198199Search results use cursor-based pagination:200201| Parameter | Description | Default | Max |202|-----------|-------------|---------|-----|203| `limit` | Results per page | 10 | 100 |204| `after` | Cursor for next page | None | - |205206**Iterating through all results:**2072081. Call the search tool with `limit=100`2092. Check the response for a `paging.next.after` value2103. If present, call again with `after` set to that value2114. Repeat until no `paging.next.after` is returned212213## Response Format214215**Single Resource:**216217```json218{219 "id": "12345",220 "properties": {221 "firstname": "John",222 "lastname": "Smith",223 "email": "john.smith@acmecorp.com",224 "company": "Acme Corporation",225 "phone": "555-123-4567",226 "lifecyclestage": "customer",227 "createdate": "2025-06-15T10:30:00.000Z",228 "lastmodifieddate": "2026-01-20T14:15:00.000Z"229 },230 "createdAt": "2025-06-15T10:30:00.000Z",231 "updatedAt": "2026-01-20T14:15:00.000Z"232}233```234235**Search Results:**236237```json238{239 "total": 47,240 "results": [241 {242 "id": "12345",243 "properties": {244 "firstname": "John",245 "lastname": "Smith",246 "email": "john.smith@acmecorp.com"247 }248 }249 ],250 "paging": {251 "next": {252 "after": "12345"253 }254 }255}256```257258## Rate Limiting259260### Rate Limit Details261262| Metric | Limit |263|--------|-------|264| Requests per 10 seconds | 100 (per OAuth app) |265| Requests per day | 500,000 (varies by plan) |266| Search requests per day | 1,000 (Free), 10,000+ (paid plans) |267268When rate limited, the MCP tool will return a 429 error. Wait before retrying. The MCP server handles OAuth token refresh automatically.269270### Plan-Based Limits271272| HubSpot Plan | Daily API Limit | Search Limit |273|-------------|----------------|--------------|274| Free | 100,000 | 1,000 |275| Starter | 250,000 | 5,000 |276| Professional | 500,000 | 10,000 |277| Enterprise | 1,000,000 | 25,000 |278279## Error Handling280281### Common Errors282283| Error | Cause | Resolution |284|-------|-------|------------|285| Tool not found | MCP server not connected | Verify OAuth credentials and server URL |286| 401 Unauthorized | OAuth token expired or invalid | Restart MCP connection to re-authenticate |287| 403 Forbidden | Insufficient scopes or plan limitation | Check HubSpot plan tier and MCP Auth App permissions |288| 404 Not Found | Invalid object ID | Verify the record ID exists |289| 409 Conflict | Duplicate record | Check for existing records before creating |290| 429 Too Many Requests | Rate limit exceeded | Wait 10 seconds and retry |291| Invalid property | Property name not valid | Use `list_*_properties` tools to check available properties |292293### Troubleshooting MCP Connection2942951. **Verify credentials** - Ensure `HUBSPOT_CLIENT_ID` and `HUBSPOT_CLIENT_SECRET` are correct2962. **Check URL** - MCP server URL must be `https://mcp.hubspot.com/`2973. **Test with a simple call** - Try `hubspot_get_user_details` to verify connectivity2984. **Re-authenticate** - Restart the MCP connection to force a fresh OAuth flow2995. **Check plan** - Ensure your HubSpot plan supports the API features you need300301## Best Practices3023031. **Filter server-side** - Use `hubspot_search_*` tools with `filterGroups` instead of listing all records3042. **Use maximum page size** - Set `limit=100` to minimize total tool calls3053. **Monitor rate limits** - Stay well under 100 requests per 10 seconds3064. **Use associations** - Link related objects (contacts to companies, deals to contacts) for full context3075. **Check properties first** - Use `list_*_properties` tools to discover available fields before searching3086. **Validate before creating** - Search for existing records before creating duplicates3097. **Use lifecycle stages** - Track contacts and companies through their lifecycle for accurate reporting3108. **Cache property lists** - Property definitions change infrequently; reference them across multiple operations311312## Related Skills313314- [HubSpot Contacts](../contacts/SKILL.md) - Contact management315- [HubSpot Companies](../companies/SKILL.md) - Company management316- [HubSpot Deals](../deals/SKILL.md) - Deal pipeline management317- [HubSpot Tickets](../tickets/SKILL.md) - Support ticket management318- [HubSpot Activities](../activities/SKILL.md) - Tasks, notes, and associations