A Model Context Protocol server for HubSpot integration providing tools for managing companies, contacts, conversations, tickets, and properties in HubSpot
Static source inference · medium confidence · detected: Logging
Deprecated protocol patterns detected
Summary
HubSpot MCP server has 16 tools with generally sound naming conventions and structured schemas, but significant gaps in descriptions, parameter documentation, and error handling. Tool names follow verb_noun patterns (get_, create_, update_), which is good. However, descriptions are inconsistent, some are minimal (e.g., 'Get activity history for a specific company' is 47 chars, acceptable but sparse), while others lack context on when to use them versus similar tools. Parameter descriptions exist but many are generic ('Additional company properties', 'Object containing the properties to update'). Output schemas are not documented in the tool definitions provided. Error handling guidance is missing, tools do not indicate whether errors are retryable, user-fixable, or fatal. The server has 6 write operations (create/update tools) with no confirmation pattern or dry-run support. No tool annotations (readOnlyHint/destructiveHint) are visible in the code. The faiss_manager and embedding_model integration suggests local caching behavior, but this is not documented in tool descriptions. Overall, the server is functional but lacks the precision and agent-optimization guidance expected of production-grade tools.
No output schemas documented. Tool definitions show input schemas but no description of what fields are returned or their types. Agents cannot reason about downstream calls or data structure expectations.
Generic parameter descriptions lack actionable context. E.g., 'Additional company properties' and 'Object containing the properties to update' do not specify what keys/values are valid, what constraints apply, or when they are required. LLMs cannot self-correct invalid input.
hubspot_create_company
Recommendations
Add explicit output schemas to every tool definition. Document the structure, field types, and meaning of returned data. Example: 'Returns {company_id: string, name: string, industry: string, revenue: number | null, created_at: ISO8601 string}.'
Enhance parameter descriptions for object/array properties. Replace 'Additional company properties' with 'Custom properties to set on the company (e.g., {"custom_field_1": "value", "annual_revenue": 1000000}). See hubspot_get_property to discover valid field names.'
Add error handling guidance to each tool description. Example: 'On 404: company not found, try hubspot_get_active_companies() to find the correct ID. On 429: rate limited, retry after 60s. On 403: permission denied, contact admin.'
Implement destructiveHint annotations on all write operations (create_company, update_company, create_contact, update_contact, update_property, create_property). Example: {"destructiveHint": true} tells agents these are risky.
Add readOnlyHint annotations to all get/list/search operations. Example: {"readOnlyHint": true} marks safe, idempotent calls.
Add idempotentHint to tools that safely retry with the same parameters (e.g., all read operations). This enables agents to auto-retry on transient errors.
Document hubspot_search_data more clearly: 'Searches the local FAISS embedding cache of recently fetched HubSpot data. Useful for finding similar companies/contacts by fuzzy match. If cache is empty or data is stale (>24h), results may be incomplete, use hubspot_get_active_companies or hubspot_get_company for fresh data.'
Spec posture evidence
Inferred effective spec: <=2025-11-25.
Relies on Logging (deprecated) - log to stderr or use OpenTelemetry
No error handling guidance. Tools do not indicate whether failures are retryable (e.g., rate-limit), user-fixable (e.g., invalid company_id), or fatal. Agents cannot plan recovery or prompt users appropriately.
Write operations (create_company, update_company, create_contact, update_contact, update_property, create_property) lack confirmation or dry-run support. No tool annotations (destructiveHint) present. Agents can accidentally create duplicates or corrupt data without safeguards.
Pagination parameters exist (limit, after, max_retries) but no documentation of page/cursor semantics or total count return values. hubspot_get_tickets specifies 'default' vs 'Closed' criteria enum with inconsistent casing, and hubspot_get_active_companies/hubspot_get_active_contacts lack clear offset/cursor guidance.
Tool descriptions lack disambiguation. 'Get company' vs 'Get active companies' distinction is not explained, when should LLM pick one over the other? No guidance on performance, data freshness, or scope differences.
hubspot_search_data tool description is vague: 'Search for similar data in stored HubSpot API responses.' No mention that it searches cached responses (via FAISS embeddings), not live HubSpot data. No guidance on freshness, cache lifetime, or fallback behavior if cache is empty.
hubspot_search_data
Clarify pagination in list tools. Example for hubspot_get_active_companies: 'Returns up to `limit` most recently modified companies. To fetch more, repeat with `after` set to the last company_id from the previous call. Returns {companies: [...], total_count: number, next_cursor: string | null}.'
Reduce required parameters where possible. For create_contact, make email optional (many contacts lack emails). For create_company, allow properties to be optional and default to empty object.
Add examples to property object descriptions to guide LLM usage. Example: 'Additional contact properties like {"phone": "555-1234", "job_title": "VP Engineering"}. See hubspot_get_property(object_type="contacts") to list available fields.'
Document confirmation patterns for write operations. Recommend adding a dry_run parameter or a separate preview tool (e.g., preview_company_creation) to let agents validate changes before committing.
Add 'WHEN TO USE' sections to disambiguate similar tools. Example: 'Use hubspot_get_company for a single known company ID. Use hubspot_get_active_companies to search by recent activity. Use hubspot_search_data to fuzzy-match by name or domain.'
Validate and document enum values. hubspot_get_tickets has 'Closed' with uppercase C, but typical API conventions use lowercase. Clarify the exact valid values and case sensitivity.
Document HubSpot-specific ID formats and naming. Are company_id, contact_id, ticket_id all integers, UUIDs, or strings? Do names require special characters or escaping? Add constraints like 'A string of 1-100 characters, alphanumeric + underscore only.'
Add failure mode examples to descriptions. Example: 'If you only have a company name, call hubspot_search_data(query="company_name") first to get the company_id. If search returns no results, the company may not exist, try creating it with hubspot_create_company.'
Return chaining IDs in all responses. If create_company returns a company_id, make sure subsequent update_company calls reference that ID in a clear, documented field. Every response should enable the next tool call without extra lookups.