Skip to content
Scalekit Docs
Talk to an Engineer Dashboard

Connect AI agents to the HubSpot MCP server

Vendor MCP
Open markdown

The HubSpot MCP connector routes your AI agent's tool calls to HubSpot's own MCP server through Scalekit. Each user signs in to HubSpot once, and Scalekit stores and refreshes their tokens, so your agent never handles credentials. It comes with 22 tools.

Tools
22
What they doRead · write · destructive
17 · 2 · 317 read2 write3 destructive
Users sign in with
OAuth app
Scalekit's or your own

Setup

  1. Install the SDK

    Terminal window
    npm install @scalekit-sdk/node dotenv
  2. Set your credentials

    Add your Scalekit credentials to your .env file. Find values in app.scalekit.com > Developers > API Credentials.

    .env
    SCALEKIT_ENVIRONMENT_URL=<your-environment-url>
    SCALEKIT_CLIENT_ID=<your-client-id>
    SCALEKIT_CLIENT_SECRET=<your-client-secret>
  3. Create the HubSpot MCP connection

    In AgentKit > Connections, create a HubSpot MCP connection. The name you give it is the connection_name your code passes. See Configure connections.

    Scalekit credentials are available for HubSpot, so you don't need to register an OAuth app. To show your own app on the consent screen, use your own credentials instead.

    Use your own OAuth app

    Register your Scalekit environment with the HubSpot MCP connector so Scalekit handles the OAuth flow and token lifecycle for your users. HubSpot MCP uses a dedicated MCP Auth App — not a Legacy App or a standard Public App.

    1. Copy the redirect URI from Scalekit

      • In Scalekit dashboard, go to AgentKit > Connections > Create Connection.
      • Search for HubSpot MCP and click Create.
      • Copy the Redirect URI from the connection details panel. It looks like:
        https://<YOUR_ENV>.scalekit.cloud/sso/v1/oauth/conn_<ID>/callback
    2. Create an MCP auth app in HubSpot

      • Log in to developers.hubspot.com and open your developer account.
      • In the left sidebar, click MCP Auth Apps (marked Beta). Do not use Legacy Apps or Projects.

      HubSpot developer portal showing the MCP Auth Apps section in the left sidebar

      • Click Create MCP auth app (top right).
      • Enter an App name, for example Agent Auth, and complete any required fields.
      • Click Create.
    3. Add the redirect URI and configure scopes

      • Inside your new MCP auth app, navigate to the Auth or OAuth settings section.

      • Under Redirect URLs, paste the Scalekit redirect URI you copied in step 1 and save.

      • Under Scopes, add the scopes your agent needs. Start with:

        crm.objects.contacts.read
        crm.objects.contacts.write
        crm.objects.companies.read
        crm.objects.deals.read

        Add additional scopes based on the tools your agent will use (for example, content scopes for landing pages and campaigns).

    4. Copy your app credentials

      • In your MCP auth app settings, find the App ID (visible in the app list as a number, for example 43664586).
      • Locate your Client ID and Client Secret under the OAuth settings.
    5. Add credentials in Scalekit

      • In Scalekit dashboard, go to AgentKit > Connections and open the HubSpot MCP connection you created.
      • Enter:
        • Client ID — from your MCP auth app
        • Client Secret — from your MCP auth app
        • Permissions — the scope strings you configured in step 3 (for example, crm.objects.contacts.read crm.objects.deals.read)
      • Click Save.
  4. Authorize a user and make your first call

    quickstart.mts
    import { ScalekitClient } from '@scalekit-sdk/node'
    import 'dotenv/config'
    import { createInterface } from 'node:readline/promises'
    const scalekit = new ScalekitClient(
    process.env.SCALEKIT_ENVIRONMENT_URL,
    process.env.SCALEKIT_CLIENT_ID,
    process.env.SCALEKIT_CLIENT_SECRET,
    )
    const actions = scalekit.actions
    const connector = 'hubspotmcp'
    const identifier = 'user_123'
    // Generate an authorization link for the user
    const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier })
    console.log('Authorize HubSpot MCP:', link)
    const rl = createInterface({ input: process.stdin, output: process.stdout })
    await rl.question('Press Enter after authorizing...')
    rl.close()
    // Make your first call
    const result = await actions.executeTool({
    connector,
    identifier,
    toolName: 'hubspotmcp_get_campaign_analytics',
    toolInput: {},
    })
    console.log(result)
    Terminal window
    npx tsx quickstart.mts

    Each user signs in once. See Authorize a user for the full flow and statuses.

Tools

Pass the exact name to execute_tool
Try in PlaygroundRequest a tool
  • hubspotmcp_discover_hubspot_schemaSearches HubSpot schema to discover available data types or look up known types directly.Read-only

    Discover Hubspot Schema

    Searches HubSpot schema to discover available data types or look up known types directly. Use SEARCH_OBJECT_TYPES when you don't know the exact type name, or GET_OBJECT_TYPES when you already know the type names (e.g. CONTACT, DEAL), or with an empty typeNameFilter list to retrieve all available types. Check readAccess/writeAccess before attempting operations on a type.

    Inputs

    querystringrequired
    The schema query to run. Choose SEARCH_OBJECT_TYPES to discover types by natural language, or GET_OBJECT_TYPES to fetch known type names directly (or all types when typeNameFilter is empty).
  • hubspotmcp_get_campaign_analyticsRetrieve engagement analytics (sessions, new contacts, influenced contacts) for one or more HubSpot campaigns.Read-only

    Get Campaign Analytics

    Retrieve engagement analytics (sessions, new contacts, influenced contacts) for one or more HubSpot campaigns.

    Inputs

    requestsarray
    Required: List of analytics requests to process. Each entry is a full CampaignAnalyticsRequest. Maximum 20 requests per batch.
  • hubspotmcp_get_campaign_asset_metricsRetrieve performance metrics for assets (emails, landing pages, CTAs) associated with a campaign.Read-only

    Get Campaign Asset Metrics

    Retrieve performance metrics for assets (emails, landing pages, CTAs) associated with a campaign.

    Inputs

    assetTypestringrequired
    The asset type name, such as LANDING_PAGE, SITE_PAGE, BLOG_POST, or MEETING_EVENT. If invalid, the error will list valid types.
    campaignCrmObjectIdintegerrequired
    The numeric ID of the campaign to get asset metrics for. Must be greater than 0.
    crmObjectIdsarray
    Optional list of CRM object IDs to scope metrics to specific assets. When omitted or empty, metrics are returned for all assets of the given assetType associated with the campaign.
    endDatestring
    End of the date range in YYYY-MM-DD format.
    startDatestring
    Start of the date range in YYYY-MM-DD format.
  • hubspotmcp_get_campaign_attribution_reportsREQUIRED FIRST STEP: before your first call, invoke tool_guidance for "get_campaign_attribution_reports" and follow it.Read-only

    Get Campaign Attribution Reports

    REQUIRED FIRST STEP: before your first call, invoke tool_guidance for "get_campaign_attribution_reports" and follow it. The dimension names, filter syntax, date-range semantics, grouping rules, and query patterns live in tool_guidance, not in this description; calling this tool without them produces wrong or failed queries. Attribution data tool: all metrics (revenue, deal amounts, deal counts, contact counts) are scoped to the closed-won deal attribution pipeline. Use for revenue, attributed deal, and attributed contact questions. For non-attribution contact queries (new contacts, influenced contacts, sessions), use read_campaign_data with GET_ANALYTICS. For deals at any stage, use read_campaign_data with operation=GET_ASSET_METRICS and assetType=DEAL, or search_crm_objects with a campaign association filter. For long-running queries, this returns a PROCESSING status with a taskId to poll for results.

    Inputs

    attributionModelstring
    Revenue attribution model for the REVENUE metric. Defaults to LINEAR. See instructions for valid values.one of LINEARFIRST_INTERACTIONLAST_INTERACTIONFULL_PATHU_SHAPEDW_SHAPEDTIME_DECAYJ_SHAPEDINVERSE_J_SHAPED
    campaignCrmObjectIdsarray
    Campaign CRM object IDs to scope the query. Empty for cross-campaign analysis.
    dimensionsarray
    How to group data (AGGREGATION mode). Max 2 per query. Omit for ungrouped totals. Key mappings: 'channels' or 'content types' (emails, ads, landing pages) -> ASSET_TYPE; specific asset names -> ASSET_TITLE; 'influence types' or 'engagement types' -> INTERACTION_TYPE; traffic/referral source -> INTERACTION_SOURCE; deal names -> DEAL_NAME; deal IDs (for links) -> DEAL.
    endDatestring
    End of date range filter (YYYY-MM-DD). Must pair with startDate or both omitted.
    filtersarray
    Server-side filters on any dimension property. See instructions for examples.
    hasReadToolInstructionsboolean
    Set to true if you have already read the usage instructions for get_campaign_attribution_reports (via tool_guidance or a prior error response). If you have not read them yet, leave this unset or set it to false and you will receive an error response containing the full instructions. Not required when polling with taskId.
    limitinteger
    Max result rows returned by the server. Defaults to 100, maximum 500. When responseFormat=CONCISE, zero-value rows are filtered client-side after the server applies this limit, so fewer rows than requested may be returned.
    metricsarray
    Required: What to measure. REVENUE for attributed revenue (use for any non-deal breakdown like channel/source/asset), DEAL_AMOUNT for per-deal or total deal value (always grouped by deal), DEAL_COUNT for unique deals, CONTACT_COUNT for unique contacts, ATTRIBUTION_COUNT for touchpoint volume.
    modestring
    Report mode. Only AGGREGATION is currently supported.one of AGGREGATIONSEARCH
    responseFormatstring
    Controls response verbosity. CONCISE (default) omits zero-value metric entries and drops rows where all metrics are zero, reducing token usage. DETAILED returns all rows and fields including zero values.one of CONCISEDETAILED
    sortByMetricstring
    Sort results by this metric (DESC by default). Use to rank rows without post-processing, e.g. REVENUE returns highest-revenue rows first.
    sortOrderstring
    Sort direction for sortByMetric. ASC or DESC. Defaults to DESC.one of ASCDESC
    startDatestring
    Start of date range filter (YYYY-MM-DD). Must pair with endDate or both omitted. Filters by deal close date for REVENUE/DEAL_AMOUNT, deal create date for DEAL_COUNT, touchpoint timestamp for CONTACT_COUNT/ATTRIBUTION_COUNT.
    taskIdstring
    Poll for results of a previously submitted query. Pass the taskId from a PROCESSING response.
  • hubspotmcp_get_campaign_contacts_by_typeRetrieve paginated contact IDs for a campaign filtered by attribution type (NEW_CONTACTS, INFLUENCED_CONTACTS, or ALL_CONTACTS).Read-only

    Get Campaign Contacts By Type

    Retrieve paginated contact IDs for a campaign filtered by attribution type (NEW_CONTACTS, INFLUENCED_CONTACTS, or ALL_CONTACTS).

    Inputs

    campaignCrmObjectIdintegerrequired
    The numeric object ID of the campaign. Must be greater than 0.
    contactTypestringrequired
    The contact attribution type: NEW_CONTACTS_FIRST_TOUCH (first marketing interaction was this campaign), NEW_CONTACTS_LAST_TOUCH (last interaction before conversion), or INFLUENCED_CONTACTS (any engagement within the date range).one of NEW_CONTACTS_FIRST_TOUCHNEW_CONTACTS_LAST_TOUCHINFLUENCED_CONTACTS
    endDatestring
    End of the date range in YYYY-MM-DD format.
    limitinteger
    Maximum number of results to return per page.
    offsetinteger
    Pagination offset — number of records to skip before returning results.
    startDatestring
    Start of the date range in YYYY-MM-DD format.
  • hubspotmcp_get_content_analytics_reportRun a content analytics report across HubSpot landing pages, website pages, and blog posts for a given date range.Read-only

    Get Content Analytics Report

    Run a content analytics report across HubSpot landing pages, website pages, and blog posts for a given date range.

    Inputs

    modestringrequired
    Which report mode to run. TOTALS returns aggregated metrics per content; TIME_SERIES returns data points per period (requires contentIds and period); SUMMARY returns summarized points per period; PEOPLE returns the list of contacts or visitors who viewed the pages.one of TOTALSTIME_SERIESSUMMARYPEOPLE
    contentIdsarray
    Content IDs to filter results to. Numeric for pages and posts; composite string (e.g. hubdb-{tableId}-{rowId}) for HubDB rows. Leave empty to query all pages in the portal. Required for TIME_SERIES and PEOPLE modes.
    endstring
    End of the reporting period in YYYY-MM-DD format.
    excludedIdsarray
    Content IDs to exclude from the result set. Same format as contentIds (numeric or composite string).
    includeMetadataboolean
    TOTALS mode: include per-content metadata (title, URL, type) in the response.
    limitinteger
    Maximum number of results to return per page.
    offsetinteger
    Pagination offset — number of records to skip before returning results.
    paginationCursorstring
    Pagination cursor from the previous response to fetch the next page.
    peopleTypestring
    PEOPLE mode: whether to return CONTACTS (known people) or VISITORS (anonymous). Required for PEOPLE mode.one of CONTACTSVISITORS
    periodstring
    TIME_SERIES or SUMMARY mode: bucket size for the time series. Required for those modes.one of DAILYWEEKLYMONTHLYQUARTERLYYEARLY
    scaleByPercentboolean
    TOTALS mode: scale metric values by their percent contribution to the totals.
    searchstring
    Free-text search to filter content by title or URL.
    sortDirectionstring
    TOTALS mode: sort direction. Ignored in other modes.one of ASCDESC
    sortMetricstring
    TOTALS mode: metric to sort by (e.g. rawViews, submissions, contacts). Ignored in other modes.
    startstring
    Start of the reporting period in YYYY-MM-DD format.
  • hubspotmcp_get_crm_objectsFetch multiple CRM objects of the same type in a single request by their IDs.Read-only

    Get Crm Objects

    Fetch multiple CRM objects of the same type in a single request by their IDs.

    Inputs

    objectTypestringrequired
    The HubSpot CRM object type to operate on (e.g. contacts, companies, deals).
    objectIdsarray
    List of object IDs to fetch. Min: 1, Max: 100
    propertiesarray
    List of property names to include in results.
  • hubspotmcp_get_organization_detailsRetrieve organization-wide details including teams, job titles, seats, account settings, and timezone.Read-only

    Get Organization Details

    Retrieve organization-wide details including teams, job titles, seats, account settings, and timezone.

    Inputs

    includearray
    Optional list of data to include in the response. Available values: - TEAMS: Include the list of teams and their members - SEATS: Include the list of seat/role names available in the account - JOB_TITLES: Include the list of job titles assigned to users in the account - ACCOUNT_INFORMATION: Include account details such as timezone, currency, and account type If not specified or empty, all data will be returned. Specify only the values you need to reduce response size. Unrecognized values will result in an error.