Hi all,
Hope you are doing well. I’m new to this platform so if apologizing if I’ve chosen incorrect topic and tags.
I’m Neel, an AI Engineer. We have integrated the HubSpot MCP server into our chatbot so users can fetch data directly from HubSpot.
I’m reaching out for guidance on an issue we’ve encountered while fetching deal information with filters.
A user requested a list of opportunities in a specific stage within a specific pipeline, along with the collaborator. To support this, the agent first called the search_properties tool with object_type = DEAL and properties such as pipeline and stage. The tool returned a standard flattened response.
The response
{
"result": [
{
"type": "enumeration",
"options": [5 items],
"name": "pipeline",
"label": "Pipeline",
"description": "The pipeline the deal is in. This determines which stages are options for the deal."
},
{
"type": "enumeration",
"options": [50 items],
"name": "hubspot_owner_id",
"label": "Deal owner",
"description": "User the deal is assigned to. Assign additional users to a deal record by creating a custom user property."
},
{
"type": "enumeration",
"options": [49 items],
"name": "dealstage",
"label": "Deal Stage",
"description": "The stage of the deal. Deal stages allow you to categorize and track the progress of the deals that you are working on."
}
],
"propertiesNotFound": [
"deal_collaborator_owner_ids"
]
}
each item is a object of value and label, where the value is an unique ID, whereas the label is what is shown to the user in the app.
The challenge is that this response does not preserve the hierarchical relationship between pipelines and their corresponding stages. As a result, the agent can identify pipeline values, deal stage values, and owner values, but it cannot reliably determine which stage belongs to which pipeline when stage names overlap across pipelines.
For example:
- P1:j1 → S1:i1, S2:i2, S3:i3, S4:i4
- P2:j2 → S5:i5, S2:i6, S3:i7, S4:i8
Here:
Prepresents pipelinesSrepresents stagesjandirepresent the corresponding IDs/values
In this case, both pipelines contain stages with the same names, but the underlying IDs are different.
If the user asks for deals in Pipeline P2 at Stage S2, the agent retrieves the available pipeline and stage values through search_properties, then calls search_crm_object with the selected IDs. However, because the property response is flattened and does not retain the parent-child mapping, the agent may incorrectly pair values, such as:
P1:j1withS2:i6P2:j2withS2:i2
These are invalid combinations, so search_crm_object correctly returns null.
The expected valid combinations would be:
P1:j1withS2:i2P2:j2withS2:i6
Because of this ambiguity, users are unable to retrieve the correct filtered deal data whenever multiple pipelines contain stage names that overlap. The workflow only succeeds when stage names are unique across pipelines.
Based on my understanding of agent behavior and LLM reasoning, the root cause appears to be the loss of hierarchical context in the tool response.
Could anyone please suggest the best way to handle this scenario?
I also want to understand why the MCP tools return JSON response instead of more structured, custom objects as list of string. Kind of __repr__ for the objects in code, which shows all the relevant attributes and their values. I know that JSON is the convention the industry follows for MCP serve, but I’m curious to know if there’s a specific reason for this choice, as we can return the structured __repr__ kind of object for each deal(in this case) as list of strings tied to response key in the json payload.
I’d really appreciate any guidance, recommendations, or best practices you can share.
Thank you for your time.