hubspot-conversations-mcp
This MCP server provides 24 tools to manage HubSpot Conversations, including reading and sending messages, managing threads, handling inboxes and channels, and integrating custom communication channels.
Thread Management: List and search threads with filters (inbox, status, contact, ticket, time). Retrieve thread details, update status (OPEN/CLOSED), archive (soft-delete, permanent after 30 days), or restore threads.
Message Operations: Access message history (including comments and system events) in a thread. Retrieve individual messages, fetch full untruncated content, and send new messages or internal comments (auto-derives channel and sender).
Inbox, Channel, and Actor Insights: List and get details for conversation inboxes, channels (email, chat, WhatsApp, etc.), and channel accounts (specific addresses/numbers). Batch-resolve actor IDs to participant profiles.
Custom Channel Integration: Create and manage accounts on custom channels, update account info (name, authorization), finalize staging connections, publish external messages into HubSpot, and update message delivery status (SENT, FAILED, READ).
Provides tools for interacting with the HubSpot Conversations API, enabling AI agents to manage conversation threads, messages, inboxes, channels, and custom channels.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@hubspot-conversations-mcpShow me my recent conversation threads"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
hubspot-conversations-mcp
MCP server for the HubSpot Conversations API — 24 tools to read conversation threads and messages, send replies, manage threads and channel accounts, and integrate custom channels, from any MCP client (Claude Code, Claude Desktop, Hermes, etc.).
Covers two HubSpot API surfaces:
Conversations API (
/conversations/conversations/2026-09-beta) — threads, messages, inboxes, channels, actorsCustom Channels API (
/conversations/custom-channels/2026-03) — channel accounts, staging tokens, publishing external messages, delivery status
How authentication works
There is exactly one way to authenticate: per-user OAuth via your organization's broker.
Every user signs in with their own HubSpot login — tokens are issued individually, stored only on their machine (~/.hubspot-conversations-mcp/tokens.json, 0600), revocable per user, and die when the user is deactivated in HubSpot. No shared credentials exist anywhere.
The broker is a small stateless service your org hosts (free on Vercel, api/ in this repo). It is the only place your HubSpot app's client secret lives; it exchanges authorization codes and refreshes tokens, stores nothing, and never sees Conversations data — all API traffic goes directly from the user's machine to HubSpot.
Related MCP server: hubspot-mcp
Org setup (one-time, ~10 minutes)
Create a HubSpot app (in a developer account, e.g. as a developer-projects app): use
"distribution": "private"and allowlist your portal. Theauthblock ofapp-hsmeta.jsonshould look like:"auth": { "type": "oauth", "redirectUrls": ["http://localhost:4573/callback"], "requiredScopes": ["oauth", "conversations.read"], "optionalScopes": ["conversations.write"], "conditionallyRequiredScopes": [] }conversations.writeis optional, matching how the CLI requests it: the defaultloginsendsconversations.readin the authorize URL'sscopeparameter andconversations.writeinoptional_scope— HubSpot rejects the consent screen whenever that split does not match the app's configuration — except theoauthscope, which HubSpot grants automatically without it being requested. (Optional scopes are granted automatically when the portal supports them; a read-only sign-in means not requesting write at all — see below.) If your org uses custom channels, addconversations.custom_channels.read/conversations.custom_channels.writetooptionalScopesas well and request them at login via--optional-scopes.If you want read-only tokens (some agents may read conversations but never send, update or archive), create a second app with only the read scope — see Read-only vs read + write for why one app can't do both:
"auth": { "type": "oauth", "redirectUrls": ["http://localhost:4573/callback"], "requiredScopes": ["oauth", "conversations.read"], "optionalScopes": [], "conditionallyRequiredScopes": [] }Both apps live behind the same broker — the read-only app's credentials go in a second pair of env vars (next step), and
login --read-onlyselects it.Apps created from the pre-0.11 template (where
conversations.writesat inrequiredScopes): either move it tooptionalScopesas above (users re-authorize on their next login), or keep it required and have users sign in withlogin --scopes conversations.read,conversations.write— read-only sign-ins are not possible with that configuration.Deploy the app and note the client ID and client secret from its Auth tab.
Deploy the broker to Vercel — one click:
The button clones this repo and prompts for the two environment variables (
HUBSPOT_OAUTH_CLIENT_ID,HUBSPOT_OAUTH_CLIENT_SECRET). Alternatively create the Vercel project manually from your fork, or wire up CI deploys via deploy-broker.yml with theVERCEL_TOKEN/VERCEL_ORG_ID/VERCEL_PROJECT_IDrepo secrets.One deployment can front both apps:
Env var
App
HUBSPOT_OAUTH_CLIENT_ID/HUBSPOT_OAUTH_CLIENT_SECRETread + write (default)
HUBSPOT_OAUTH_READ_ONLY_CLIENT_ID/HUBSPOT_OAUTH_READ_ONLY_CLIENT_SECRETread-only (optional)
The client's
login --read-onlyselects the read-only app, and the choice travels with the tokens so refreshes use the right app's credentials. The broker's/api/configadvertises which apps exist and their scopes, sologinandsetuprequest exactly the right split automatically. Optional fine-tuning:HUBSPOT_OAUTH_SCOPES/HUBSPOT_OAUTH_OPTIONAL_SCOPESoverride what the default app's logins request (e.g. to add custom-channel scopes), andHUBSPOT_OAUTH_READ_ONLY_SCOPES/HUBSPOT_OAUTH_READ_ONLY_OPTIONAL_SCOPESdo the same for the read-only app (default: justconversations.read).Share the broker URL (e.g.
https://your-broker.vercel.app) with the team — it is not a secret, and neither is the client ID (the CLI fetches it from the broker's/api/config). SettingHUBSPOT_OAUTH_BROKER_URLorg-wide (dotfiles, MDM, onboarding docs) makes all commands flag-free.
Because the app is private-distribution and allowlisted, only your own org's portals can complete a login against your broker — each org runs its own broker with its own app, so tokens never cross organizational trust boundaries.
Per user
Interactive setup (recommended)
npx -y hubspot-conversations-mcp setupThe wizard walks through everything:
Broker — asks whether your org already has a broker; if not, it shows the setup guide (and links back here). The URL is verified live against
/api/configbefore continuing.Sign in — the wizard asks which access level to sign in with: read & write, or read-only (via the broker's read-only app when it has one, otherwise as a best-effort reduced-scope request). Brokers that advertise a scope profile decide the level themselves and skip the question. Then your browser opens HubSpot's consent screen; sign in with your own HubSpot login. Tokens land on your machine and auto-refresh through the broker.
Agents — pick which AI agents to configure with an arrow-key multiselect (↑/↓ to move, space to toggle): Claude Desktop, Claude Code, and/or Hermes (Nous Research hermes-agent). Each is configured automatically — no credentials are written to any config file.
Manual / scripted
npx -y hubspot-conversations-mcp login --broker-url https://your-broker.vercel.appnpx -y hubspot-conversations-mcp install --client all--client takes claude-desktop, claude-code, hermes, both (the two Claude clients), all, or a comma-separated combination:
claude-desktop — merges the server into
claude_desktop_config.json(existing servers preserved; timestamped backup first). Restart Claude Desktop afterwards.claude-code — runs
claude mcp add … -- npx -y hubspot-conversations-mcp(prints the command if theclaudeCLI is unavailable). Add--scope userto register across all your projects (the setup wizard defaults to this).hermes — merges the server into
~/.hermes/config.yamlundermcp_serverswithenabled: true(backup first; YAML comments are not preserved). Verify withhermes mcp test hubspot-conversations.
whoami shows the active sign-in, logout removes it. Use --dry-run to preview installs, --config-path / --hermes-config-path for non-standard config locations.
Read-only vs read + write
Write access is a property of the token, not of the server: the server looks at the
scopes granted at login and only registers the tools that token can actually use. HubSpot
enforces scopes server-side either way — the gating just keeps the tool list honest, so a
read-only sign-in gets a server without SendConversationMessage,
UpdateConversationThread or ArchiveConversationThread instead of tools that fail
with 403.
One app cannot give the same portal both access levels. HubSpot grants scopes per
app installation on the portal, not per authorization: once an app is connected with
write access, a later login requesting fewer scopes just re-attaches to the existing
grant and returns a token that still carries write (scopes only shrink when they are
removed from the app's auth settings entirely and the user reauthorizes — see HubSpot's
auth settings
and reauthorization
changelogs). The server will honestly show that: whoami reports read + write and the
write tools stay registered, because the token really can write.
Genuinely read-only tokens therefore come from a second, read-only app (org setup
above): an app whose only conversations scope is conversations.read, registered on the
same broker via HUBSPOT_OAUTH_READ_ONLY_CLIENT_ID / HUBSPOT_OAUTH_READ_ONLY_CLIENT_SECRET.
login --read-only signs in through that app — its tokens can never write, no matter
what is requested — and the profile travels with the stored tokens so refreshes keep
using the right app. Use a separate token store to keep it next to your main sign-in:
HUBSPOT_TOKEN_STORE_PATH=~/.hubspot-conversations-mcp/tokens-ro.json \
npx -y hubspot-conversations-mcp login --broker-url https://your-broker.vercel.app --read-onlyThen register a second MCP entry pointing at that store, e.g. for Claude Code:
claude mcp add hubspot-conversations-ro --env HUBSPOT_TOKEN_STORE_PATH=$HOME/.hubspot-conversations-mcp/tokens-ro.json -- npx -y hubspot-conversations-mcpThe default registration keeps the read + write token; hubspot-conversations-ro only
ever sees the 13 read tools — and its token couldn't write even outside MCP.
Details:
--read-onlyrequires the broker to have the read-only app configured (loginfails with a pointer here otherwise). Without a second app, the wizard's "Read-only (best effort)" choice — or--scopes conversations.read— requests a reduced grant from the main app, which yields a truly read-only token only if the app was never granted write on that portal (otherwise the existing grant wins, see above).When the broker advertises a scope profile for its default app (
HUBSPOT_OAUTH_SCOPES), plainloginrequests exactly that; a wizard run against such a broker (with no read-only app) shows the resulting access level instead of asking.--scopessets the app-required scopes and--optional-scopesthe app-optional ones, e.g.--optional-scopes conversations.write,conversations.custom_channels.read,conversations.custom_channels.write— custom-channel tools are likewise only offered when theconversations.custom_channels.*scopes were granted. HubSpot rejects the consent screen if the split does not match the app's scope configuration.The rare token store without recorded scopes (scope introspection failed during a pre-0.11 login) makes the server offer all tools, with HubSpot alone enforcing access; since 0.11
loginalways records scopes, falling back to the requested ones. Re-runloginto fix such a store.Upgrading from 0.10: tokens signed in with the default scopes never carried
conversations.custom_channels.*, so the 8 custom-channel tools disappear from the tool list on upgrade — they previously appeared but always failed with 403. Re-login with--optional-scopesincluding those scopes (and the app updated to offer them) to use them.whoamiprints the access level of the active sign-in (from the token's live scopes when reachable).The tool list is fixed when the server starts — after changing access level with a re-login, restart the MCP client/server to apply the new gating.
Broker endpoints
Endpoint | Purpose |
| Public app metadata (client IDs and scope profiles of the configured apps) so users only need the broker URL |
|
|
|
|
One-click bundle for Claude Desktop (MCPB)
The repo ships a manifest.json following Anthropic's MCP Bundle format:
npm run bundleThis produces a .mcpb file. Open it with Claude Desktop (or drag it into Settings → Extensions) for a one-click install. Run npx -y hubspot-conversations-mcp login once first — the extension uses the same per-user sign-in.
Releasing to npm
Releases ship automatically from main. Bump version in package.json and manifest.json plus SERVER_VERSION in server.ts — all three must match — and merge. The release workflow spots that the version isn't on npm yet, runs the tests, creates the v<version> tag + GitHub release with generated notes, and publishes that release to npm with provenance (auth via the NPM_TOKEN repo secret). Pushes without a version bump are no-ops.
prepublishOnly builds and runs the full test suite before the actual upload. The published package contains only dist/, manifest.json, README and LICENSE.
Configuration
Environment variable | Description |
| Your org's broker URL, used by |
| OAuth token store location (default |
| Default sender for |
| Default |
| Default |
| Default |
On the broker deployment (never on user machines): HUBSPOT_OAUTH_CLIENT_ID / HUBSPOT_OAUTH_CLIENT_SECRET (read + write app), optionally HUBSPOT_OAUTH_READ_ONLY_CLIENT_ID / HUBSPOT_OAUTH_READ_ONLY_CLIENT_SECRET (read-only app used by login --read-only), and optionally HUBSPOT_OAUTH_SCOPES / HUBSPOT_OAUTH_OPTIONAL_SCOPES (+ _READ_ONLY_ variants) to override the scopes logins request.
Tools
Tool availability follows the scopes granted at login (see
Read-only vs read + write): read tools need
conversations.read, write tools need conversations.write, and the custom-channel
group needs conversations.custom_channels.read / .write. Tokens with no recorded
scopes get all 24 tools.
Threads
Tool | Description |
| List/search threads — filter by inbox, OPEN/CLOSED, contact, ticket, time window; paginated |
| Get a single thread (status, inbox, channel, assignee, contact) |
| Set OPEN/CLOSED, archive or restore a thread |
| Soft-delete a thread (permanently deleted after 30 days) |
Messages
Tool | Description |
| Message history of a thread (messages, comments, system events); paginated |
| Get a single message |
| Original (untruncated) text/richText of a message |
| Send a message to the customer — or an internal comment with |
Inboxes, channels & actors
Tool | Description |
| Conversation inboxes / help desks |
| Channel types (email, chat, …) |
| Connected accounts (specific email addresses / numbers) |
| Resolve actor IDs ( |
Custom channels (offered only when the token carries the conversations.custom_channels.* scopes)
Tool | Description |
| Create an account on a custom channel |
| List accounts on a custom channel |
| Get one custom-channel account |
| Rename or (de)authorize a channel account |
| Finalize a staging-token connection (public apps) |
| Publish an external message into HubSpot |
| Get a custom-channel message |
| Report delivery status: SENT / FAILED / READ |
Sending replies
SendConversationMessage only requires thread_id and text. Everything else is derived:
channel_id/channel_account_id— taken from the thread'soriginalChannelId/originalChannelAccountIdrecipients— the senders of the latest incoming message (i.e. a normal reply)sender_actor_id— falls back toHUBSPOT_DEFAULT_SENDER_ACTOR_ID
Pass any of them explicitly to override. The full request body can also be supplied as a stringified JSON request_body (typed fields win on conflict), and calling with mode="get_request_schema" returns the raw body schema. The same pattern applies to PublishCustomChannelMessage.
Development
npm test # vitest — unit + in-memory MCP integration tests
npm run typecheck # tsc --noEmit (CLI + broker functions)
npm run build # compile to dist/
npm run bundle # build a .mcpb one-click bundle for Claude DesktopThe integration tests run the full MCP server against a stubbed fetch, so no HubSpot account is needed to develop.
Notes
The client retries once on
429/502/503(honoringRetry-After, capped at 10s) and once more with a refreshed token on401.Thread assignee endpoints (
PUT/DELETE /threads/{id}/assignee) exist in the HubSpot API but are not currently exposed as tools. Add them insrc/tools/threads.tsif needed.
Available Tools
24 toolsArchiveConversationThreadArchive a conversation threadADestructive
Archives a conversation thread, marking it for deletion. The thread is permanently deleted after 30 days.
| Name | Required | Description | Default |
|---|---|---|---|
| thread_identifier | Yes | The unique identifier of the conversation thread to archive |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds valuable behavioral detail beyond the destructiveHint annotation by disclosing that the thread is permanently deleted after 30 days. This informs the agent about the irreversible nature and lifecycle.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, zero wasted words. The action is front-loaded and the additional detail about 30-day deletion is concise and relevant.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single-parameter tool with destructiveHint, the description is sufficient. It covers the purpose, the deletion timeline, and there is no output schema to explain. The context is complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% with a clear description for thread_identifier. The tool description adds no additional parameter semantics, but the schema already fully documents the parameter, so baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb 'archive' and the resource 'conversation thread', and adds 'marking it for deletion' to clarify the action. This distinguishes it from siblings like UpdateConversationThread or RetrieveThreadById.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear context (archiving marks for deletion) and the 30-day retention implies a specific use case. However, it does not explicitly name alternatives or exclusion scenarios, so it falls short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
CreateChannelAccountCreate a channel account (custom channel)A
Create a new account within a specific custom communication channel. Enables multiple accounts to communicate over a single channel with different delivery identifiers. Requires the conversations.custom_channels.write scope.
| Name | Required | Description | Default |
|---|---|---|---|
| inbox_id | Yes | The unique identifier for the inbox where the channel account will be created | |
| channel_id | Yes | The unique identifier for the custom channel where the account will be created | |
| account_name | Yes | The name of the account to be created for the channel | |
| is_authorized | Yes | Whether the account should be authorized. Set to true for authorized accounts | |
| delivery_identifier_type | No | Type of delivery identifier | |
| delivery_identifier_value | No | The delivery identifier value: an E.164 phone number, an email address, or a channel-specific ID |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden. It discloses the required OAuth scope ('conversations.custom_channels.write') and hints at the behavior of using different delivery identifiers. However, it does not describe side effects, return values, or any restrictions beyond the scope, leaving some behavioral aspects opaque.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences with no redundant wording. The first sentence states the core action, and the second adds value by explaining the use case and required scope. It is front-loaded and efficient.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's moderate complexity (6 parameters, no output schema), the description covers the essential context: purpose, scope, and conceptual usage. It could be more complete by explicitly noting that the inbox and channel must already exist or by describing the response, but the core information is present.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3. The description adds some context about delivery identifiers that helps interpret delivery_identifier_type/value, but it does not provide additional meaning beyond what the schema already describes for each parameter.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action ('Create a new account') and the resource ('within a specific custom communication channel'). It also explains the purpose ('Enables multiple accounts to communicate over a single channel with different delivery identifiers'), which distinguishes it from update/retrieve siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies when to use this tool (when creating a channel account) and provides context about multiple accounts per channel, but it does not explicitly mention alternatives or when not to use it. There is no direct comparison to UpdateChannelAccountInfo or other sibling tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
GetChannelAccountDetailsGet channel account detailsBRead-only
Fetch detailed information about a specific HubSpot channel account using the channel account ID, such as its status and configuration.
| Name | Required | Description | Default |
|---|---|---|---|
| channel_account_id | Yes | The unique ID of the HubSpot channel account to retrieve details for |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations declare readOnlyHint=true, and the description's 'Fetch' aligns with read-only behavior. The description adds context about the type of information returned (status and configuration) but does not disclose error behavior, permission requirements, or other operational details beyond the annotation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, focused sentence that front-loads the action and resource. No unnecessary words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple read-only tool with one parameter and no output schema, the description covers the core purpose. However, the presence of a similarly named sibling ('RetrieveChannelAccountDetails') means the description should clarify the tool's specific scope, which it does not.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The single parameter channel_account_id is fully documented in the schema (100% coverage). The description reiterates using the ID but adds no additional semantic meaning beyond what the schema already provides.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('Fetch') and identifies the resource ('specific HubSpot channel account') and the input ('using the channel account ID'). It mentions the kind of details ('status and configuration'). However, it doesn't differentiate from the sibling tool 'RetrieveChannelAccountDetails', which appears to serve a similar purpose.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no guidance on when to use this tool versus alternatives like 'RetrieveChannelAccountDetails' or 'RetrieveChannelAccounts'. No prerequisites or exclusions are provided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
GetCustomChannelAccountsGet custom channel accountsARead-only
Fetch the list of accounts associated with a specific custom channel, identified by the channel ID.
| Name | Required | Description | Default |
|---|---|---|---|
| after | No | Pagination cursor from paging.next.after | |
| limit | No | Max results per page | |
| custom_channel_id | Yes | The unique identifier of the custom channel to retrieve accounts for |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, so the read-safe nature is covered. The description adds the association context but does not disclose pagination behavior, rate limits, or error handling beyond what the schema already provides.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
One clear sentence, front-loaded with the verb, and no redundant words. It is concise and well-structured.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple list-fetch tool, the description covers the core purpose. The pagination parameters (after, limit) imply a paged response, but the description doesn't explicitly state the return envelope. Given the annotations and schema, this is nearly complete, with a minor gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema covers all 3 parameters with descriptions (100% coverage), so the baseline is 3. The tool description primarily restates the custom_channel_id purpose without adding new semantic meaning beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses the specific verb 'Fetch' and identifies both the resource ('list of accounts') and the scope ('specific custom channel, identified by channel ID'). This clearly distinguishes it from siblings like RetrieveChannelAccounts, which likely target non-custom channels.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description clearly indicates the tool is for fetching accounts for a specific custom channel by ID, giving clear context on when to use it. However, it does not explicitly name alternative tools or state when not to use it, so it stops short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
GetCustomChannelMessageDetailsGet custom channel message detailsARead-only
Get the details of a specific message sent through a custom channel — message content, sender information, and timestamps.
| Name | Required | Description | Default |
|---|---|---|---|
| channel_id | Yes | The unique identifier for the custom channel the message was sent through | |
| message_id | Yes | The unique identifier of the message to retrieve details for |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The readOnlyHint annotation already signals a safe read operation, and the description adds behavioral context by listing exactly what detail categories are returned (message content, sender info, timestamps), which is useful since no output schema is provided.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, front-loaded sentence that conveys the action, target, and key returned details without any wasted words or repetition of schema fields.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple read-only tool with two required parameters and no output schema, the description adequately covers purpose and expected return fields. The only minor gap is the lack of explicit usage guidance relative to sibling tools.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%; both channel_id and message_id are already well-documented in the schema. The description adds no additional parameter syntax or constraints beyond the schema, so the baseline of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly identifies the action (Get), the resource (details of a specific message sent through a custom channel), and the scope (message content, sender information, timestamps), distinguishing it from general message history tools like GetMessageHistoryForThread or RetrieveFullMessageContent.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies use when retrieving details of a specific custom-channel message but does not explicitly contrast it with sibling tools such as RetrieveFullMessageContent or RetrieveThreadMessage, nor does it provide when-not-to-use conditions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
GetInboxDetailsGet inbox detailsARead-only
Retrieve detailed information about a specific conversation inbox by its ID.
| Name | Required | Description | Default |
|---|---|---|---|
| inbox_id | Yes | The unique identifier for the conversation inbox you wish to retrieve details for |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations already declare readOnlyHint: true, so the read-only nature is covered. The description adds no additional behavioral context such as return format, pagination, error handling, or permissions. Since the annotation covers the main safety aspect, the description is acceptable but does not go beyond what annotations provide.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, clear sentence of 12 words, with the key action ('Retrieve detailed information') front-loaded. There is no redundancy, filler, or repetition of the title. Every word contributes to the meaning, making it highly concise and well-structured.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple read-only tool with one required parameter and no output schema, the description is largely sufficient. It identifies the resource and the parameter. The phrase 'detailed information' is somewhat vague in terms of what fields will be returned, but given the low complexity and existing annotations, the description provides adequate context for an agent to select and invoke the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema fully describes the single parameter inbox_id ('The unique identifier for the conversation inbox you wish to retrieve details for'). With 100% schema description coverage, the description does not need to add parameter detail. It adds no extra semantics beyond the schema, so the baseline score of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's function: 'Retrieve detailed information about a specific conversation inbox by its ID.' It specifies a concrete verb ('Retrieve') and resource ('conversation inbox'), and the phrase 'by its ID' aligns with the required parameter. It does not explicitly differentiate from sibling tools like ListConversationInboxes, but the word 'specific' conveys single-item retrieval, making the purpose unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies when to use the tool—when you have an inbox ID and need detailed information—but it does not provide explicit guidance on when to use it versus alternatives (e.g., ListConversationInboxes for enumeration). No exclusions or alternative tool references are mentioned, so usage context is only implied, not stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
GetMessageHistoryForThreadGet message history for a threadARead-only
Retrieve the message history for a given conversation thread by its ID (messages, comments and system events like assignments and status changes). Paginated: pass after from paging.next.after to fetch the next page.
| Name | Required | Description | Default |
|---|---|---|---|
| after | No | Pagination cursor from paging.next.after | |
| limit | No | Max results per page | |
| thread_id | Yes | The unique identifier for the conversation thread whose message history is to be retrieved | |
| is_archived | No | Set true if the thread is archived |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already provide readOnlyHint=true, and the description adds valuable behavioral context: it specifies pagination via the `after` cursor and discloses that the result includes system events like assignments and status changes. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, front-loaded with the action, and every word adds value. The pagination hint is concise and directly actionable.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema exists, but the description compensates by listing the types of entries included (messages, comments, system events) and explaining pagination. Given the moderate complexity, this is sufficient for an AI agent to understand the tool's behavior.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The description reinforces the `after` cursor usage but does not add new meaning beyond what the schema already documents for each parameter.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: 'Retrieve the message history for a given conversation thread by its ID.' It enumerates content types (messages, comments, system events), distinguishing it from sibling tools like RetrieveThreadMessage (single message) or RetrieveThreadById (thread metadata).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description clearly indicates when to use this tool (when full thread history is needed) and provides pagination instructions. It does not explicitly name alternatives or exclusions, but the context is clear and the sibling list reinforces the distinction from single-message retrieval.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ListConversationChannelsList conversation channelsBRead-only
Retrieve a list of conversation channels (e.g. email, live chat, forms, WhatsApp), with optional filters and sorting if needed.
| Name | Required | Description | Default |
|---|---|---|---|
| sort | No | Fields to sort by | |
| after | No | Pagination cursor from paging.next.after | |
| limit | No | Max results per page |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The readOnlyHint annotation covers the safety profile, so the description doesn't need to restate that. However, it mentions 'optional filters' that are not supported by the input schema, which is misleading. It also adds no meaningful behavioral context such as return format, pagination behavior, or authentication requirements.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, front-loaded sentence that names the action and resource, with examples. It is concise, though 'if needed' is filler and the unsupported 'filters' claim slightly detracts from precision.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the simplicity of the tool (read-only, 3 optional params, no output schema), the description is mostly adequate. It lacks explicit return-value details and pagination behavior, and it does not differentiate itself from similar list tools. Still, it provides enough to understand the basic purpose.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema describes all three parameters with 100% coverage, so the baseline is 3. The description adds 'sorting if needed' which aligns with the sort parameter, but the 'filters' mention is unsupported and adds no real semantic value beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool retrieves a list of conversation channels and provides concrete examples (email, live chat, forms, WhatsApp), which distinguishes it from sibling tools like ListConversationInboxes or RetrieveChannelDetails. The mention of 'optional filters and sorting' is slightly overreaching since no filter parameter exists, but the core purpose is clear.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies when to use the tool (to get a list of channels) and mentions optional sorting, but it does not explicitly contrast it with sibling tools or state when not to use it. The absence of any alternative guidance or exclusions keeps this at the 'implied usage' level.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ListConversationInboxesList conversation inboxesARead-only
Fetch a list of conversation inboxes (shared inboxes and help desks), with optional filters and sorting to customize the results.
| Name | Required | Description | Default |
|---|---|---|---|
| sort | No | Fields to sort by | |
| after | No | Pagination cursor from paging.next.after | |
| limit | No | Max results per page | |
| is_archived | No | Set true to list archived inboxes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already provide readOnlyHint=true, and the description aligns with a read operation ('Fetch'). It adds minimal behavioral context beyond that, such as the scope of inboxes and the existence of filters/sorting, but does not disclose pagination details or response structure. This is adequate but not rich.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence, front-loaded with the verb and resource, and every word adds value. It is concise and well-structured.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple list tool with 4 optional parameters (fully documented in schema), no required parameters, and readOnlyHint annotation, the description adequately conveys the tool's purpose and scope. It could mention response pagination, but the schema covers the 'after' cursor, so the information is available.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Input schema covers 100% of parameters with clear descriptions (sort, after, limit, is_archived). The description's mention of 'optional filters and sorting' reinforces these but adds no extra semantic detail. Baseline of 3 applies since schema does the heavy lifting.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses the specific verb 'Fetch' and clearly identifies the resource as 'conversation inboxes (shared inboxes and help desks)' with optional filters and sorting. This distinguishes it from sibling tools like GetInboxDetails (getting a single inbox) and ListConversationChannels (listing channels).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear context that this is for listing conversation inboxes and customizing results with filters/sorting, implying its use for enumeration tasks. It does not explicitly mention alternatives or exclusions, but the context is sufficient for an agent to infer when to use it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
PublishCustomChannelMessagePublish a message to a custom channelA
Publish a message over a specified custom channel into HubSpot Conversations — used by custom-integrated messaging channels to sync external messages into HubSpot. Provide the message either as typed fields or as a stringified JSON request_body (typed fields win on conflict). Requires channelAccountId, senders and recipients. Call with mode='get_request_schema' to inspect the raw request body schema.
| Name | Required | Description | Default |
|---|---|---|---|
| mode | No | 'get_request_schema' returns the request body schema; default is 'execute' | |
| text | No | Plain text content of the message | |
| senders | No | Message senders, e.g. [{deliveryIdentifier: {type: 'CHANNEL_SPECIFIC_OPAQUE_ID', value: 'user-1'}, name: 'Name'}] | |
| rich_text | No | Rich text/HTML content | |
| timestamp | No | ISO 8601 timestamp of the message | |
| recipients | No | Message recipients, same shape as senders | |
| attachments | No | Attachments, e.g. [{fileId: '123', type: 'FILE'}] | |
| request_body | No | Optional stringified JSON request body (see mode='get_request_schema') | |
| in_reply_to_id | No | ID of the message this is a reply to | |
| custom_channel_id | Yes | The unique ID of the custom channel where the message will be published | |
| channel_account_id | No | The channel account the message belongs to | |
| integration_thread_id | No | Your external conversation/thread ID | |
| associate_with_contact_id | No | CRM contact ID to associate the message with | |
| integration_idempotency_id | No | Unique ID for idempotency |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the sparse openWorldHint annotation, it discloses that typed fields win over request_body on conflict, request_body must be stringified JSON, and that channelAccountId, senders, and recipients are de facto required even though the schema only lists custom_channel_id as required. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three dense sentences with no filler. Front-loads the core action, then adds mode and requirement guidance; every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 14-parameter tool with no output schema, the description captures purpose, mode, body alternatives, requirements, and how to inspect the full schema. However, it does not qualify the required-fields statement by mode and does not describe return behavior, leaving some gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema descriptions cover all 14 parameters (100%), so baseline is 3. The description adds meaningful semantics: the typed-fields-vs-request_body priority, the mode's schema-inspection purpose, and execute-time required fields. This exceeds schema alone but leaves detailed field semantics to the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description opens with a specific verb and resource: 'Publish a message over a specified custom channel into HubSpot Conversations' and clearly scopes it to custom-integrated messaging channels syncing external messages. This differentiates it from sibling tools like SendConversationMessage.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides clear use-case context ('custom-integrated messaging channels to sync external messages into HubSpot') and operational guidance (typed fields vs request_body, mode='get_request_schema' to inspect schema). Does not explicitly name when-not-to-use alternatives, so not a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ResolveConversationActorsResolve conversation actorsARead-only
Resolve a list of ActorIds to detailed participant information in one batch call — use this to understand who the participants in a conversation are.
| Name | Required | Description | Default |
|---|---|---|---|
| actor_ids | Yes | A list of Actor IDs to resolve, e.g. ['A-12345', 'V-67890'] |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare readOnlyHint=true, so the read-only behavior is already known. The description adds the batch-call behavior and the fact that it returns participant info, but does not disclose additional traits such as error handling or partial result behavior. With annotations covering safety, this is adequate but not rich.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, efficient sentence that states the action, object, and purpose without redundancy. It is front-loaded with the key information and contains no fluff.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple tool with one parameter and no output schema, the description sufficiently covers purpose and usage. It mentions 'detailed participant information' as the return concept. It could have added a note about unresolved IDs or response format, but given the simplicity and read-only annotation, it is nearly complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema covers the only parameter (actor_ids) with a clear description and example ('['A-12345', 'V-67890']'), achieving 100% schema coverage. The tool description adds minimal extra meaning beyond the schema, so the baseline of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('Resolve') with a clear resource ('a list of ActorIds') and outcome ('detailed participant information'). It distinguishes itself from sibling tools by emphasizing the batch aspect and the conversation participant context, making it clear this is different from single-actor lookups like RetrieveActorDetails.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description states when to use it: 'use this to understand who the participants in a conversation are.' It also implies batch use ('in one batch call'), which guides the agent to choose this over single-actor resolve tools. It does not explicitly name alternatives or exclusions, but the context is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
RetrieveActorDetailsRetrieve actor detailsARead-only
Retrieve details of a specific actor (conversation participant) by actor ID. Actor IDs are prefixed by type: 'A-' agent/user, 'V-' visitor/contact, 'B-' bot, 'E-' email, 'S-' system, 'I-' integrator.
| Name | Required | Description | Default |
|---|---|---|---|
| actor_id | Yes | The unique identifier for the actor whose details are to be retrieved, e.g. 'A-12345' |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations already include readOnlyHint=true, so the read-only nature is known. The description adds the ID prefix scheme, but no additional behavioral details such as return format, error cases, or rate limits. This is acceptable for a simple read operation, but not exceptional beyond the annotation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is only two sentences: the first states the primary purpose and input, and the second adds essential context about actor ID prefixes. It is front-loaded, concise, and every word serves a purpose.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool has a single parameter and a readOnlyHint annotation, but no output schema. The description explains the input well but does not specify what 'details' includes or what the response structure looks like, leaving a notable gap for an AI agent that needs to understand the return value.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema describes actor_id as a string with a generic example, but the description adds meaningful semantics by explaining the prefix types ('A-', 'V-', 'B-', 'E-', 'S-', 'I-'). This helps the agent construct and validate IDs, going beyond the schema's coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses the specific verb 'Retrieve' and identifies the resource as 'details of a specific actor (conversation participant)' using an actor ID. It also explains the ID prefix conventions, clearly distinguishing it from sibling tools like ResolveConversationActors or channel account retrieval tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description clearly implies the tool is for fetching a single actor's details when the actor ID is known, as indicated by 'by actor ID'. It provides context with the ID prefix breakdown, but it does not explicitly contrast with alternatives or state exclusions, so it stops short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
RetrieveChannelAccountDetailsRetrieve custom channel account detailsARead-only
Retrieve detailed metadata about a channel account on a custom channel, including its channel, inbox ID, and delivery identifiers.
| Name | Required | Description | Default |
|---|---|---|---|
| channel_account_id | Yes | Unique identifier for the specific channel account to retrieve details about | |
| channel_identifier | Yes | The unique identifier for the custom channel |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotation readOnlyHint=true already indicates a safe read operation. The description adds context about the returned fields (channel, inbox ID, delivery identifiers) but does not disclose the full response shape, pagination, or error behavior. It provides some value beyond the annotation but not extensive.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence, directly states the action, and includes the key metadata fields. No unnecessary words or repetition.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
There is no output schema, so the description must convey return behavior. It lists some returned fields but uses 'including,' which suggests a non-exhaustive list. It also lacks any mention of error scenarios or edge cases, leaving some ambiguity for a retrieval tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so both parameters are already documented in the schema. The description does not add any new parameter semantics beyond that, matching the baseline for high schema coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses the specific verb 'Retrieve' and clearly identifies the resource as 'detailed metadata about a channel account on a custom channel.' It also lists the specific metadata fields included (channel, inbox ID, delivery identifiers), which helps distinguish it from the sibling tool GetChannelAccountDetails.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied by the description: this tool is for retrieving details of a custom channel account. However, there is no explicit when-to-use guidance or mention of alternatives, and the sibling GetChannelAccountDetails could overlap.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
RetrieveChannelAccountsRetrieve channel accountsARead-only
Retrieve a list of channel accounts — concrete instances of a channel connected to an inbox (e.g. a specific email address or phone number). Supports optional filters and sorting to refine the results.
| Name | Required | Description | Default |
|---|---|---|---|
| sort | No | Fields to sort by | |
| after | No | Pagination cursor from paging.next.after | |
| limit | No | Max results per page | |
| inbox_id | No | Filter by inbox IDs | |
| channel_id | No | Filter by channel IDs | |
| is_archived | No | Set true to list archived channel accounts |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare readOnlyHint=true, matching the read-only description, so no contradiction. The description adds conceptual background and filter/sort capabilities, but does not disclose pagination behavior, default filters (e.g., non-archived only), or response format. With no output schema, more behavioral detail would be helpful.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences, front-loaded with purpose, and includes a useful definition parenthetical. Every sentence earns its place with no unnecessary verbosity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With 6 optional parameters and no output schema, the description could more thoroughly explain pagination, default behavior, and return value structure. It covers the core purpose but leaves behavioral details to the schema, which only partially compensates for the missing output schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and parameters are self-describing. The description only generically mentions 'optional filters and sorting' without detailing any parameters. As per baseline for high schema coverage, a score of 3 is appropriate; description adds no significant semantic value beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states the tool retrieves a list of channel accounts and defines what a channel account is, distinguishing it from single-entity tools like RetrieveChannelAccountDetails. The verb 'Retrieve' combined with 'list' makes the scope explicit, and the example clarifies the concept.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies use for listing and filtering channel accounts, with optional filters and sorting. It provides clear context though it does not explicitly mention alternatives or exclusions. The 'list' wording differentiates it from single-account retrieval tools, but no direct comparison is given.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
RetrieveChannelDetailsRetrieve channel detailsARead-only
Retrieve comprehensive details about a specific channel in HubSpot Conversations by providing the channel ID.
| Name | Required | Description | Default |
|---|---|---|---|
| channel_id | Yes | The unique ID of the channel to retrieve details for |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotation readOnlyHint=true already indicates a safe read operation, and the description is consistent with that. However, the description adds no additional behavioral context such as specific data returned, pagination, or permissions, so it merely meets the baseline without exceeding it.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, clear sentence with no unnecessary words. It front-loads the primary action and resource, making it highly concise and well-structured.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the simplicity of the tool (one parameter, no output schema) and the read-only annotation, the description is largely sufficient. It could be improved by specifying what types of details are included, but it is not critically incomplete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has 100% coverage with a clear description for channel_id. The tool description does not add any additional parameter semantics beyond the schema, so the baseline of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool retrieves comprehensive details about a specific channel using a channel ID. It is specific about the verb and resource, but does not explicitly distinguish itself from sibling tools like RetrieveChannelAccounts or GetChannelAccountDetails.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies the tool is used when you have a channel ID and need details, but it does not provide explicit guidance on when to prefer this over alternatives or when not to use it. No exclusions or alternative tools are mentioned.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
RetrieveConversationThreadsRetrieve conversation threadsARead-only
Retrieve conversation threads from HubSpot Conversations. You can apply optional filters (inbox, OPEN/CLOSED status, associated contact or ticket, time window) and sorting to tailor the results. Paginated: pass after from the previous response's paging.next.after.
| Name | Required | Description | Default |
|---|---|---|---|
| sort | No | Fields to sort by, e.g. latestMessageTimestamp | |
| after | No | Pagination cursor from paging.next.after | |
| limit | No | Max results per page | |
| inbox_id | No | Only threads in these inbox IDs | |
| is_archived | No | Set true to list archived threads instead | |
| thread_status | No | Filter by thread status | |
| associated_ticket_id | No | Only threads associated with this ticket ID | |
| associated_contact_id | No | Only threads associated with this CRM contact ID | |
| include_ticket_association | No | Include associated ticket IDs on each thread | |
| latest_message_timestamp_after | No | Only threads with messages after this ISO 8601 timestamp, e.g. 2026-08-01T00:00:00Z | |
| latest_message_timestamp_before | No | Only threads with messages before this ISO 8601 timestamp |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
readOnlyHint=true is already provided, and the description adds pagination behavior (pass `after` from paging.next.after), which is useful. There is no contradiction with annotations, and the read-only nature means no destructive side effects need to be disclosed.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, front-loaded with the primary purpose, then adding filter and pagination details. No wasted words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with 11 parameters and no output schema, the description provides a solid overview including filters, sorting, and pagination. It mentions the response's paging structure, but does not specify the overall return format or defaults, leaving minor gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3. The description groups filters by category (inbox, status, associated contact/ticket, time window) and mentions sorting, but does not add details beyond what is already in the schema descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states it retrieves conversation threads from HubSpot Conversations with a specific verb and resource. It outlines filtering and sorting capabilities, distinguishing it as a list/filter tool, but does not explicitly contrast it with sibling tools like RetrieveThreadById.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The context is clear: use this tool to retrieve conversation threads with optional filters and sorting. It does not explicitly mention alternatives or exclusions, but the plural 'threads' and filter options imply it is for listing rather than single-thread retrieval.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
RetrieveFullMessageContentRetrieve full original message contentARead-only
Retrieve the original text and rich text of a message — useful for untruncated content when the message's truncationStatus indicates it might be truncated.
| Name | Required | Description | Default |
|---|---|---|---|
| message_id | Yes | The unique identifier for the message | |
| conversation_thread_id | Yes | The unique identifier for the conversation thread containing the message |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With readOnlyHint=true in the annotations, the non-mutating nature is already declared. The description adds that the tool returns original text and rich text and addresses truncation, but it does not elaborate on the response format, content structure, or error behavior, leaving the description to carry only partial behavioral detail.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, well-structured sentence that immediately states the action and resource, then follows with a concise trigger condition. Every word contributes to the meaning, with no redundancy or filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's low complexity (two string parameters, read-only annotation, no output schema), the description sufficiently covers purpose, usage context, and return content. Combined with the fully documented schema and annotations, an agent has all needed information to invoke it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema covers both parameters with clear descriptions for message_id and conversation_thread_id, achieving 100% coverage. The tool description adds no parameter-specific meaning, so the baseline of 3 is appropriate as no compensation is needed.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool retrieves the original text and rich text of a message, with the specific qualifier of providing full untruncated content. This distinguishes it from sibling retrieval tools by emphasizing the 'full original' content and the truncation context.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly says it is useful when the message's truncationStatus indicates it might be truncated, giving clear when-to-use guidance. It does not name alternative tools or provide when-not guidance, but the use case is directly and appropriately contextualized.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
RetrieveThreadByIdRetrieve a thread by IDARead-only
Retrieve detailed information about a conversation thread by ID: status, inbox, original channel, assignee and associated contact.
| Name | Required | Description | Default |
|---|---|---|---|
| is_archived | No | Set true if the thread is archived | |
| conversation_thread_id | Yes | The unique identifier for the conversation thread you wish to retrieve | |
| include_ticket_association | No | Include associated ticket IDs |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare readOnlyHint=true, so the tool's read-only nature is already conveyed. The description adds context by listing the specific information returned, which helps the agent anticipate the response contents. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, front-loaded sentence that states the action, resource, and key return fields without any redundant or filler text. Every word contributes to the tool's purpose.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description takes on the responsibility of indicating return content. It lists several key fields (status, inbox, original channel, assignee, contact) which convey the nature of the response; while not exhaustive, it is adequate for a simple get-by-id tool with three documented parameters.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema provides descriptions for all three parameters, including the required conversation_thread_id and optional booleans is_archived and include_ticket_association. The description does not add any parameter-specific semantics beyond the schema, so a baseline score of 3 is appropriate given full schema coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb 'Retrieve' and clearly identifies the resource and scope ('conversation thread by ID') while enumerating the detail fields (status, inbox, original channel, assignee, contact). This distinguishes it from sibling tools like RetrieveConversationThreads (list) and UpdateConversationThread (mutate).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description clearly implies use when a single thread's details are needed by ID, and the context is unambiguous. However, it does not explicitly mention when not to use this tool or name alternative tools for related tasks like getting message history or updating threads.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
RetrieveThreadMessageRetrieve a single thread messageARead-only
Retrieve the details of a specific message within a conversation thread using the message ID.
| Name | Required | Description | Default |
|---|---|---|---|
| thread_id | Yes | The unique identifier of the conversation thread from which to retrieve the message | |
| message_id | Yes | The unique identifier for the specific message within the thread |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The readOnlyHint annotation already establishes this as a safe read operation. The description adds minimal behavioral context beyond scope (specific message within a thread), but does not disclose return format or edge-case behavior. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single, front-loaded sentence with no filler. It communicates the core action, resource, and scope efficiently.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple read operation with full parameter documentation and a read-only annotation, the description is sufficiently complete. It lacks return-value details but that is not critical given the straightforward nature of the tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so parameters are fully documented in the schema. The description only reiterates that a message ID is used without adding extra semantic detail.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool retrieves details of a specific message within a conversation thread using a message ID. It distinguishes from sibling tools like RetrieveThreadById (which retrieves the thread itself) and GetMessageHistoryForThread (which lists messages).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The usage context is implied: use this when you need details for a specific message by ID. However, it does not explicitly mention when to prefer this over RetrieveFullMessageContent or other alternatives, nor does it state exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
SendConversationMessageSend a message in a conversation threadA
Send a new message on an existing conversation thread — delivered to the customer on the thread's channel (set message_type=COMMENT for an internal note instead). Provide the content either as typed fields (text, recipients, …) or as a stringified JSON request_body; typed fields win on conflict. Missing channel_id/channel_account_id are taken from the thread, missing recipients are derived from the latest incoming message, and sender_actor_id falls back to HUBSPOT_DEFAULT_SENDER_ACTOR_ID. Call with mode='get_request_schema' to inspect the raw request body schema.
| Name | Required | Description | Default |
|---|---|---|---|
| mode | No | 'get_request_schema' returns the request body schema; default is 'execute' | |
| text | No | Plain text content of the message | |
| subject | No | Optional email subject | |
| rich_text | No | Optional HTML content | |
| thread_id | Yes | The unique identifier for the conversation thread where the message will be sent | |
| channel_id | No | Channel ID; defaults to the thread's originalChannelId | |
| recipients | No | Recipients; defaults to the senders of the latest incoming message | |
| attachments | No | Optional attachments (see HubSpot attachment schemas); defaults to [] | |
| message_type | No | MESSAGE (default) is sent to the customer; COMMENT is an internal note | |
| request_body | No | Optional stringified JSON request body (see mode='get_request_schema') | |
| sender_actor_id | No | Sending actor, e.g. 'A-12345'. Defaults to HUBSPOT_DEFAULT_SENDER_ACTOR_ID | |
| channel_account_id | No | Channel account ID; defaults to the thread's originalChannelAccountId |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With only an openWorldHint annotation (which gives no safety/behavior info), the description carries the burden of behavioral disclosure. It explains important fallback behavior: missing channel_id/channel_account_id are taken from the thread, missing recipients are derived from the latest incoming message, and sender_actor_id defaults to HUBSPOT_DEFAULT_SENDER_ACTOR_ID. It also spells out field precedence and the mode='get_request_schema' capability, which goes well beyond the schema. It doesn't mention side effects or permissions, but for a message-sending tool this is substantial transparency.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but well-structured, front-loading the core purpose in the first clause. It is a few long sentences, but each clause carries unique information about delivery, internal notes, request_body, fallbacks, and schema inspection. A bit of trimming could improve readability, but it's not padded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 12-parameter tool with no output schema and minimal annotations, the description is highly complete. It explains the central execution flow, alternative invocation modes, parameter precedence, and default behaviors. It doesn't describe the return value, but the absence of an output schema is offset by the detailed operational guidance. It could be more explicit about what happens after a message is sent, but overall it is sufficient for safe invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3. The description adds meaningful parameter semantics beyond the schema: 'typed fields win on conflict' between typed fields and request_body, and it clarifies default derivation for channel_id, channel_account_id, recipients, and sender_actor_id. This helps the agent understand how parameters interact and what will happen if they are omitted.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: 'Send a new message on an existing conversation thread — delivered to the customer on the thread's channel.' It names the resource (conversation thread), the action (send), and distinguishes it from sibling tools like RetrieveThreadMessage or UpdateConversationThread. It also adds nuance by explaining that message_type=COMMENT is for internal notes, making the purpose even more precise.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives solid context for when to use the tool: 'on an existing conversation thread' and 'delivered to the customer.' It also clarifies a key decision point with 'set message_type=COMMENT for an internal note instead.' However, it does not explicitly name sibling alternatives or provide when-not-to-use guidance, so it stops short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
UpdateChannelAccountInfoUpdate channel account infoA
Update the name and/or authorization status of a channel account on a custom channel — including disabling the account by setting set_authorization_status to false.
| Name | Required | Description | Default |
|---|---|---|---|
| channel_id | Yes | The unique identifier for the custom channel | |
| channel_account_id | Yes | The unique identifier for the channel account to be updated | |
| channel_account_name | No | The new display name for the channel account | |
| set_authorization_status | No | New authorization status. Set to false to disable the account |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden. It does disclose the important side-effect that setting set_authorization_status to false disables the account. However, it omits other behavioral details such as required permissions, reversibility, or the effect of updating only one field.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, front-loaded sentence with no wasted words. It states the action, the target resource, and a key behavioral example, all in a compact form.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple four-parameter mutation tool with no output schema and no annotations, the description sufficiently covers the tool's purpose and key behavior. It could add more about return values or explicitly differentiate from UpdateChannelAccountStaging, but overall it is adequate.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The description adds little beyond the schema: 'name and/or authorization status' maps to the existing optional parameters, and the disabling note is already present in the schema description for set_authorization_status.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses the specific verb 'Update', identifies the resource as 'channel account', and scopes it to 'custom channel', which clearly distinguishes it from sibling tools like CreateChannelAccount, GetChannelAccountDetails, and UpdateChannelAccountStaging.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage by stating what can be updated (name and/or authorization status) and how to disable the account, but it does not explicitly contrast this tool with alternatives like UpdateChannelAccountStaging or provide exclusions. Hence it gives clear context but no direct selection guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
UpdateChannelAccountStagingUpdate channel account staging tokenA
Update the account name and delivery identifier of a channel account staging token (public app connection flow) in HubSpot Conversations.
| Name | Required | Description | Default |
|---|---|---|---|
| channel_id | Yes | The unique identifier for the custom channel | |
| account_name | Yes | The name of the account to be updated | |
| account_token | Yes | The staging token identifying the channel account being connected | |
| delivery_identifier_type | Yes | Type of delivery identifier | |
| delivery_identifier_value | Yes | The delivery identifier value: an E.164 phone number, an email address, or a channel-specific ID |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. It only states the update action without mentioning side effects, mutability, reversibility, auth requirements, or any other behavioral traits. This is a significant gap for a mutation tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, concise sentence that front-loads the verb and resource, and contains no filler or redundant information. It efficiently captures the essence of the tool.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
While the description covers the basic purpose and context, it lacks usage guidelines and behavioral transparency. Given the existence of similar sibling tools and the absence of annotations/output schema, the description is only minimally complete for safe and correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3. The description adds context by mentioning 'account name' and 'delivery identifier', which maps to the schema parameters, but does not add detail beyond what the schema already provides. The staging token context slightly aids understanding but is not a major addition.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action ('Update the account name and delivery identifier') and the resource ('channel account staging token'), with the context of 'public app connection flow' that distinguishes it from sibling tools like UpdateChannelAccountInfo. It is a specific verb+resource statement.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies the usage context (staging token, public app connection flow) but does not explicitly state when to use this tool versus alternatives like UpdateChannelAccountInfo. No exclusions or alternative guidance are provided, so the usage is only implied.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
UpdateConversationThreadUpdate or restore a conversation threadA
Update a single thread's status (OPEN/CLOSED) or archive/restore it. Set is_thread_archived=true to archive, false to restore an archived thread.
| Name | Required | Description | Default |
|---|---|---|---|
| thread_status | No | Set the thread's status to OPEN or CLOSED | |
| thread_identifier | Yes | The unique identifier for the conversation thread to update or restore | |
| is_thread_archived | No | Set to true to archive or false to restore the thread |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description discloses the core behavior: updating status and archiving/restoring threads, including specific boolean semantics. However, with no annotations provided, the description carries the full burden but does not mention potential side effects, permissions, reversibility beyond 'restore', or error conditions. It adds minimal context beyond what the title and schema already convey.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences long, directly front-loaded with the primary purpose, and uses precise language. Every sentence contributes useful information without unnecessary elaboration. It is exceptionally concise and well-structured.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool is simple with 3 parameters and full schema coverage. The description adequately explains the main actions and boolean usage. However, the absence of annotations and output schema means the description does not cover return values or error conditions, and it does not distinguish from the ArchiveConversationThread sibling. For a simple update tool, this is mostly complete but could be improved with additional context.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already provides 100% coverage for all three parameters, with descriptions for each. The tool description repeats the boolean semantics in the schema ('Set to true to archive or false to restore') but adds no new meaning about parameter interactions or constraints. Since schema coverage is high, a baseline score of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states that the tool updates a single conversation thread's status (OPEN/CLOSED) or archives/restores it. It identifies a specific verb (update) and resource (single conversation thread), making the purpose clear. However, it does not explicitly differentiate from sibling tools like ArchiveConversationThread, which likely overlaps with the archive/restore functionality.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies when to use the tool (when you need to change a thread's status or archive/restore it) but provides no explicit guidance on alternatives or exclusions. There is no mention of using ArchiveConversationThread for archive-only operations or any context about choosing this tool over others. The usage context is implied but not fully articulated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
UpdateMessageStatusUpdate custom channel message statusB
Update the delivery status of a message within a custom channel: SENT, FAILED, or READ. For FAILED messages, include an error message for clarification.
| Name | Required | Description | Default |
|---|---|---|---|
| message_id | Yes | Unique identifier of the message to be updated | |
| message_status | Yes | The new status of the message | |
| channel_identifier | Yes | The unique identifier for the custom channel where the message is located | |
| error_message_for_failed_status | No | Error message clarifying the failure. Only used when message_status is FAILED |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of disclosing behavioral traits. It implies a mutation through 'Update' but does not describe side effects, reversibility, authorization needs, or error handling. The only extra detail is the conditional error message for FAILED status, which is minimal.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a concise two-sentence summary, front-loaded with the main purpose and then a helpful conditional note. Every sentence earns its place, with no redundant or irrelevant information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the lack of annotations and output schema, the description is incomplete for a mutation tool. It does not explain return values, potential errors, preconditions, or the impact of the update. The agent lacks critical context for safe and correct usage.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The description recounts the enum values and the conditional error message parameter, but does not add meaning beyond what the schema already provides. It adds no new semantic depth.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the specific action (update delivery status) and the resource (message within a custom channel), enumerating the allowed statuses (SENT, FAILED, READ). This distinguishes it from sibling tools like UpdateConversationThread or SendConversationMessage, which serve different purposes.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides no explicit guidance on when to use this tool versus alternatives. It only mentions a conditional parameter usage for FAILED messages, but does not set it apart from other update tools or specify scenarios where it should or should not be used.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
24 tool updates
v0.4.0- First observed
ArchiveConversationThread - First observed
CreateChannelAccount - First observed
GetChannelAccountDetails - First observed
GetCustomChannelAccounts - First observed
GetCustomChannelMessageDetails - First observed
GetInboxDetails - First observed
GetMessageHistoryForThread - First observed
ListConversationChannels - First observed
ListConversationInboxes - First observed
PublishCustomChannelMessage - First observed
ResolveConversationActors - First observed
RetrieveActorDetails - First observed
RetrieveChannelAccountDetails - First observed
RetrieveChannelAccounts - First observed
RetrieveChannelDetails - First observed
RetrieveConversationThreads - First observed
RetrieveFullMessageContent - First observed
RetrieveThreadById - First observed
RetrieveThreadMessage - First observed
SendConversationMessage - First observed
UpdateChannelAccountInfo - First observed
UpdateChannelAccountStaging - First observed
UpdateConversationThread - First observed
UpdateMessageStatus
TDQS
Scored across 24 tools
Several tools have overlapping purposes, such as GetChannelAccountDetails vs RetrieveChannelAccountDetails and UpdateConversationThread vs ArchiveConversationThread, which both handle archiving. The distinction between general and custom channel tools is not immediately clear, making misselection likely.
Tool names mix Get, Retrieve, List, Update, Create, Send, Publish, and Archive without a consistent pattern. For example, 'GetChannelAccountDetails' and 'RetrieveChannelAccountDetails' are nearly identical in structure but use different verbs. The naming lacks a predictable verb_noun convention.
With 24 tools, the server is on the heavy side, though the HubSpot Conversations domain is broad enough to warrant many operations. However, several tools (like the multiple channel account retrieval variants) could be consolidated, making the count feel inflated.
The tool set covers the essential conversation lifecycle: listing and retrieving threads, sending and viewing messages, managing inboxes/channels/accounts, and archiving. Minor gaps exist, such as no way to create a thread or update an assignment, but these are not critical for typical workflows.
Maintenance
Related MCP Connectors
The HubSpot MCP Server acts as a bridge that enables AI assistants and Large Language Models to securely interact with HubSpot CRM data through natural conversation, without requiring users to understand complex API structures. It provides read-only access to standard CRM objects (contacts, companies, deals, tickets, products, invoices, and more) and their associations, secured via OAuth 2.0, allowing AI agents to perform tasks like summarizing deals, fetching company updates, and looking up record changes.
MCP server for the HubSpot Integrations Center HubDB: search and retrieve integration data.
MCP server for Sendbird — chat users, channels, members, and messages from your AI client.
MCP server that lets AI assistants use all OneSchema features exposed via the public API.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceThis MCP Server enables users to interact with HubSpot's marketing events API, allowing management of marketing event data through natural language commands.1-
- AlicenseAqualityDmaintenanceA read-only MCP server that exposes HubSpot CRM data (contacts, deals, companies, quotes) to AI agents, enabling natural language queries.9MIT
- AlicenseNot gradedqualityDmaintenanceMCP server for the HubSpot CRM API with tools for managing contacts, companies, deals, tickets, and CRM workflows. Generated with MCPForge. Sensitive operations can be protected with permissions, audit logs, and approval workflows.17 npmMIT
- AlicenseNot gradedqualityDmaintenanceA Model Context Protocol (MCP) server that provides AI assistants with full access to HubSpot CRM. Manage contacts, companies, deals, pipelines, and associations directly from Claude, Cursor, or any MCP-compatible client.5 npmMIT