tools/call over
POST /hubspot/mcp. The connector is connected through OAuth (HubSpot login; see
Forbind HubSpot CMS).
Endpoint:
https://mcp.consile.ai/hubspot/mcp. HubSpot CMS is its own named
connector with only its own tools.Write safety: guardrail model
The nine write tools split into two tiers based on reversibility:- Draft operations run freely. Creating a page, editing a blog post draft, or upserting a HubDB row all target the unpublished draft buffer. Nothing reaches the live site and the change can be discarded. No confirmation required.
- Publishing and destructive actions require
confirm: true. These are: pushing a page draft live (publish_page), publishing a blog post draft (publish_blog_post), publishing a HubDB table draft to live pages (publish_hubdb_table), and discarding a HubDB draft (reset_hubdb_draft). Withoutconfirm: true, the tool returns aWritePreviewdry-run and calls no HubSpot API.
WritePreview shape
When a write action requires confirmation butconfirm is omitted or false, the tool
returns this shape instead of calling HubSpot:
confirm: true added.
Draft-first default on create
New pages and blog posts are always created withstate: "DRAFT". The connector
enforces this regardless of what the caller sends, so nothing is accidentally published
on first create.
Portal tier requirement
The OAuth scopes this connector requests (content, hubdb, business-intelligence)
require the connected HubSpot portal to be on one of:
- CMS Hub or Content Hub (any paid tier)
- Marketing Hub Professional or Enterprise
Authentication
HubSpot CMS uses the standard OAuth authorization-code flow with refresh token. Each tenant authorizes Consile’s HubSpot app and theirrefresh_token is vaulted under
(tenantId, "hubspot"). Access tokens expire after roughly 30 minutes and are
renewed silently by the platform’s refreshing vault. The AI never sees the token.
OAuth scopes: content, hubdb, business-intelligence, oauth (the last is
auto-injected by HubSpot on every grant and is not a functional scope).
Revoking access. There is no upstream revoke in the portal in v1. To pull access
back from HubSpot, uninstall the Consile app in HubSpot’s connected apps settings.
Disconnecting in the Consile portal deletes the vaulted token immediately.
Shared parameters
Paging
List tools use cursor-based paging. Passafter from paging.next.after in the
previous response to retrieve the next page.
Max items to return in this page (1-100).
Cursor from a previous response’s
paging.next.after.Page type
Which page tree:
"site" (website pages) or "landing" (landing pages).HubDB table reference
HubDB table numeric id (preferred) or unique table name.
Read tools: pages (4 tools)
list_pages
List website or landing pages with paging. Passarchived: true to list archived
pages instead of live ones.
List archived pages instead of live ones.
{ results, paging } where each result includes id, name, slug,
state, htmlTitle, metaDescription, publishDate, archivedAt, createdAt,
updatedAt.
get_page
Retrieve a single site or landing page (the live/published version) by id.The page id.
get_page_draft
Read the unpublished draft buffer of a page to inspect pending edits before publishing.The page id.
get_page but reflects staged edits).
list_page_revisions
List prior published revisions of a page for review or rollback planning.The page id.
{ results, paging } where each revision includes id, createdAt,
createdBy.
Read tools: blog (4 tools)
list_blog_posts
List blog posts with paging. Passarchived: true to list archived posts.
List archived posts instead of live ones.
{ results, paging } where each result includes id, name, slug,
state, contentGroupId, htmlTitle, metaDescription, publishDate, tagIds,
authorName, createdAt, updatedAt.
get_blog_post
Get a single blog post by id. Setdraft: true to read the draft buffer instead of
the live version.
The blog post id.
Read the draft buffer instead of the live version.
postBody (HTML content).
list_blog_tags
List blog tags with paging.{ results, paging } where each tag includes id, name, slug,
createdAt, updatedAt.
list_blog_authors
List blog authors with paging. Authors are referenced by posts; this is a read-through of the author registry.{ results, paging } where each author includes id, displayName,
email, slug, avatar.
Read tools: HubDB (5 tools)
list_hubdb_tables
List the account’s HubDB tables with id, name, label, column metadata, row count, and publish state.{ results, paging } where each table includes id, name, label,
columns (array with type, name, label, options), rowCount, publishedAt.
get_hubdb_table
Get a single HubDB table’s full definition including column schema: types, options, andforeignTableId/foreignColumnId for FOREIGN_ID columns. Call this before
writing rows to understand the expected value types.
columns array.
list_hubdb_rows
List rows of a published HubDB table with paging. Returns each row’s cell values per column.{ results, paging } where each row includes id, values (map of
column name to cell value).
get_hubdb_row
Get a single published HubDB row by rowId.The row id.
{ id, values }.
export_hubdb_table
Export a HubDB table’s data as a CSV or Excel file. Returns the raw file content.Export format:
"CSV" or "EXCEL".{ tableIdOrName, format, data } where data is the raw file content
as a string.
Read tools: analytics (1 tool)
get_traffic_analytics
Read traffic and page-view analytics over a date range. Optionally broken down by content, source, geolocation, or UTM campaign.Requires Marketing Hub Professional/Enterprise on the connected portal. The
business-intelligence scope gates this endpoint.How to break the traffic down. One of:
totals, sessions, sources,
geolocation, pages, landing-pages, utm-campaigns.Aggregation period. One of:
total, daily, weekly, monthly,
summarize/daily, summarize/weekly, summarize/monthly.Start date in
YYYYMMDD format (inclusive).End date in
YYYYMMDD format (inclusive).Max breakdown rows to return (up to 1000).
Write tools (9 guardrailed)
create_page_draft
Create a new site or landing page as an unpublished draft. State is forced toDRAFT
regardless of what you pass; nothing goes live on create. Publish later with
publish_page.
Does not require confirmation (reversible draft operation).
Internal page name.
Path to the template/theme file the page uses.
URL slug (path) for the page.
SEO
<title> for the page.SEO meta description.
update_page_draft
Edit a page’s draft buffer (name, slug, SEO title, SEO description) without touching the live page. Publish the change later withpublish_page.
Does not require confirmation (draft buffer only, live page untouched).
The page id.
publish_page
Push a page’s unpublished draft changes live to the public website. Requiresconfirm: true. Without it, returns a WritePreview dry-run describing
exactly what would be published.
The page id.
Set
true to apply. Omit or false to receive a WritePreview.WritePreview if not confirmed.
create_blog_post_draft
Create a new blog post as an unpublished draft. State is forced toDRAFT. Requires
the target blog’s contentGroupId (read it from an existing post via list_blog_posts
or find it in the HubSpot UI). Publish later with publish_blog_post.
Does not require confirmation (reversible draft operation).
The blog (content group) id this post belongs to.
Post title / internal name.
URL slug for the post.
Post body HTML.
SEO
<title>.SEO meta description.
update_blog_post_draft
Edit a blog post’s draft buffer (title, slug, body, SEO) without touching the live post. Publish later withpublish_blog_post.
Does not require confirmation (draft buffer only, live post untouched).
The blog post id.
Post body HTML.
publish_blog_post
Push a blog post’s draft changes live to the public site. Requiresconfirm: true. Without it, returns a WritePreview dry-run.
The blog post id.
Set
true to apply. Omit or false to receive a WritePreview.WritePreview if not confirmed.
upsert_hubdb_row_draft
Create a new row (omitrowId) or update an existing one (pass rowId) in a
HubDB table’s draft. Changes are staged and invisible on live pages until
publish_hubdb_table is called.
Call get_hubdb_table first to inspect column types. Cell values must match each
column’s type (for example: FOREIGN_ID columns expect arrays, select columns expect
option objects, date columns expect epoch milliseconds).
Does not require confirmation (staged in draft, nothing live until publish).
Existing row id to update. Omit to create a new row.
Map of
columnName to cell value, typed per the column schema.publish_hubdb_table
Publish a HubDB table’s draft (schema and rows) so the changes appear on live pages. Any prior HubDB row write is invisible until this is called. Requiresconfirm: true. Without it, returns a WritePreview dry-run.
Set
true to apply. Omit or false to receive a WritePreview.WritePreview if not
confirmed.
reset_hubdb_draft
Discard all unpublished draft changes on a HubDB table, reverting the draft to the current live/published version. Destructive: all staged row and schema edits are lost. Requiresconfirm: true. Without it, returns a WritePreview dry-run.
Set
true to apply. Omit or false to receive a WritePreview.WritePreview if not
confirmed.
Code examples
Tool names are namespaced
hubspot__<tool> in Claude/ChatGPT (the AI invokes
these automatically). The bare names (e.g. list_pages) are used here for
readability.An expired or revoked access token returns
AccessTokenExpiredError. Because
HubSpot uses a refresh_token flow, silent renewal normally prevents this. If
it does surface, reconnect via the portal to issue a fresh token pair. See
Errors & limits.