Production-grade, read-only MCP server for HubSpot CRM
Five read-only tools with complete input schemas and descriptions. Naming is clear and verb-prefixed (list_, get_, search_). Descriptions are detailed (150 - 250 chars) and explain WHAT, WHEN, and WHAT-RETURNS. All parameters have types and descriptions. Output structure is documented in descriptions (e.g., 'each block starting with its numeric id'). However, output schemas are not formally declared in JSON Schema format, they are described in prose only. Error handling is present (HubSpotError caught and returned as text) but lacks recovery guidance. No tool annotations (readOnlyHint, etc.). Parameter validation is strong (record_id, object_type regex checks in code), but not exposed in schema constraints.
Fetch all records of `to_object_type` associated with a single record (identified by `from_object_type` and numeric `from_record_id`). Returns each associated record's numeric `id` and the association type(s) linking them (category, typeId, and label if available).
Fetch a single record by `object_type` and numeric `record_id`. `properties` is an optional comma-separated list of property names to return (default: the same sensible per-object set as list_records).
List all properties (fields) available on `object_type` (contacts, companies, deals, tickets, or a custom object's name), capped at a sensible skim of the most important ones (a heavily customized portal can have hundreds). Each property's name, type, and label are returned.
List recent records of `object_type` (contacts, companies, deals, tickets, or a custom object's name). `properties` is an optional comma-separated list of property names to return (default: a sensible per-object set for the four standard objects; HubSpot's own default properties for anything else). Returns up to `limit` records (default: HUBSPOT_MCP_ITEM_LIMIT), each block starting with its numeric `id`.
Output schemas not formally declared. Descriptions mention structure (e.g., 'each block starting with its numeric id', 'returns total count') but no JSON Schema output type is visible. LLMs cannot reliably parse prose-only output specs.
No tool annotations (readOnlyHint, destructiveHint, idempotentHint). All five tools are read-only, but this is not declared in the tool definition, only in the server docstring and risk field. Clients cannot infer safety properties.
Error messages lack recovery guidance. HubSpotError is caught and returned as text, but no actionable next steps are provided. E.g., 'Invalid object_type' should suggest 'Try list_properties(object_type) to discover valid types.'
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | C | 63 | 2026-07-28+ | v2 |
Full-text search for records of `object_type` (contacts, companies, deals, tickets, or a custom object's name) matching `query` (plain text, never filter syntax). `properties` is an optional comma-separated list of property names to return (default: the same sensible per-object set as list_records). Returns up to `limit` records (default: HUBSPOT_MCP_ITEM_LIMIT), each block starting with its numeric `id`, plus a `total` count of all matches.
Parameter constraints (object_type, record_id validation) are enforced in code (_valid_object_type, _valid_record_id) but not exposed in JSON Schema. Schema shows type:string with no pattern or enum, LLMs cannot see the constraints.
Pagination for list_records and search_records is not exposed. Code mentions 'paging.next.after' in docstring but no cursor/offset parameter is visible in the schema. Agents cannot iterate large result sets.