From hubspot
Provides patterns and best practices for HubSpot MCP tools: connection, OAuth 2.0 + PKCE, scopes, rate limiting, error handling, and CRM search API usage.
How this skill is triggered — by the user, by Claude, or both
Slash command
/hubspot:api-patternsWhen to use
When working with available tools, OAuth 2.0 + PKCE authentication, scopes, Streamable HTTP transport, rate limiting, error handling, and best practices in the HubSpot MCP tools. Use when: hubspot api, hubspot query, hubspot filter, hubspot rate limit, hubspot authentication, hubspot mcp, hubspot oauth, hubspot request, hubspot scope, hubspot tools, hubspot connection, or hubspot search api.
The summary Claude sees in its skill listing — used to decide when to auto-load this skill
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 re...
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.
HubSpot hosts an official remote MCP server. Authentication uses OAuth 2.0 with PKCE, handled by the mcp-remote bridge:
MCP Server URL: https://mcp.hubspot.com/
Transport: Streamable HTTP
Authentication: OAuth 2.0 + PKCE (handled automatically by mcp-remote)
export HUBSPOT_CLIENT_ID="your-client-id"
export HUBSPOT_CLIENT_SECRET="your-client-secret"
{
"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"
}
}
}
}
HubSpot MCP automatically derives required OAuth scopes from the tools you use. You do not need to manually configure scopes. For example:
crm.objects.contacts.read and crm.objects.contacts.writecrm.objects.deals.read and crm.objects.deals.writeHubSpot 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.
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
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"
}
]
}
]
}
| 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"} |
{
"sorts": [
{
"propertyName": "createdate",
"direction": "DESCENDING"
}
]
}
Sort Directions: ASCENDING, DESCENDING
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:
limit=100paging.next.after valueafter set to that valuepaging.next.after is returnedSingle Resource:
{
"id": "12345",
"properties": {
"firstname": "John",
"lastname": "Smith",
"email": "[email protected]",
"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": "[email protected]"
}
}
],
"paging": {
"next": {
"after": "12345"
}
}
}
| 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.
| 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 | 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 |
HUBSPOT_CLIENT_ID and HUBSPOT_CLIENT_SECRET are correcthttps://mcp.hubspot.com/hubspot_get_user_details to verify connectivityhubspot_search_* tools with filters instead of listing all recordslimit=100 to minimize total tool callsfilterGroups to narrow results rather than fetching everythinglist_*_properties tools to discover available fields before searchingnpx claudepluginhub wyre-technology/msp-claude-plugins --plugin hubspotAutomates HubSpot CRM operations (contacts, companies, deals, tickets, properties) via Rube MCP and Composio. Useful for managing HubSpot data without manual UI interaction.
Automates HubSpot CRM operations (contacts, companies, deals, tickets, properties) via Rube MCP and Composio integration. Useful for syncing CRM data, managing pipelines, and creating custom properties.
Automates HubSpot CRM operations (contacts, companies, deals, tickets, properties) via Rube MCP using Composio integration.