Multi-tenant Model Context Protocol server for the HubSpot CRM. Provides tools to read and write HubSpot CRM objects (contacts, companies, deals, tickets), search them, manage associations, and add notes.
Server has 15 well-named tools with consistent verb_noun patterns (search_*, get_*, create_*, update_*, list_*). All tools have descriptions (avg ~80 chars, within baseline 34-392). Input schemas are present with type definitions and parameter descriptions. However, output schemas are NOT documented, responses are inferred from HubSpot API but never formally declared. Parameter descriptions lack constraints (e.g., limit 1-100 is enforced in code but not stated in schema descriptions). Error handling returns structured objects but lacks recovery guidance (no 'try search_contacts first' hints). No tool annotations (readOnlyHint/destructiveHint) despite clear read/write distinction. Missing idempotency guidance for create/update tools.
Create a new company. Common props: name, domain, industry.
Create a new contact. Common props: email, firstname, lastname, phone, company.
Create a new deal. Common props: dealname, amount, dealstage, pipeline.
Create a note engagement, optionally associated to contacts/companies/deals.
Get a single company by ID.
Get a single contact by HubSpot contact ID.
Output schemas not documented. LLMs cannot plan downstream tool calls or extract required fields (e.g., contact_id from search_contacts for use in get_contact). Responses are inferred from HubSpot API but never formally declared in tool definitions.
Parameter constraints (limit 1-100, properties array) are enforced in code but not stated in schema descriptions. LLMs cannot read code, they rely on descriptions to understand valid ranges. This forces trial-and-error or hallucinated values.
No tool annotations (readOnlyHint/destructiveHint/idempotentHint). Server clearly distinguishes read (search_*, get_*, list_*) from write (create_*, update_*) tools, but this is not declared in tool metadata. Agents cannot infer safety or retry behavior.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | B | 79 | 2026-07-28+ | v2 |
Get a single deal by ID.
List associations from an object to another object type.
List HubSpot owners/users.
Search HubSpot companies by free-text query.
Search HubSpot contacts by free-text query (matches name, email, phone, company).
Search HubSpot deals by free-text query.
Update properties on an existing company.
Update properties on an existing contact.
Update properties on an existing deal.
Error responses lack recovery guidance. _request() returns {error: true, message: '...'} but does not suggest next steps. E.g., 'Contact not found' should suggest 'Try search_contacts() with a partial name.'
create_* and update_* tools accept generic 'properties' dict with no schema validation. LLMs cannot discover valid property names (email, firstname, etc.) without external HubSpot documentation. No enum or pattern constraints.