Context
I’m integrating a third-party MCP server with ChatGPT. The server exposes three tools:
search_businessesId_by_name— searches a business by name, returns a short JSON list with IDssearch_businesses— searches by activity/category, returns a structured JSON listget_business_details_and_phone— fetches full details for a givenbusiness_id
The expected flow for a named-entity query (e.g. “give me all info on Domaine de Locguénolé in Kervignac”) is:
search_businessesId_by_name→ returns{ id: "00257381", name: "Domaine de Locguénolé", ... }get_business_details_and_phone(business_id: "00257381")→ returns full details
Observed behavior
Step 1 — search_businessesId_by_name is called correctly, but its result is wrapped in a non-standard format in the debug panel:
{
"content_type": "multimodal_text",
"parts": [
"Citation Marker: @filecite@turn0file0@",
"[L1] { [L2] ... [L3] \"name\": \"Domaine de Locguénolé\" ... }"
]
}
The actual business id ("00257381") is buried inside the fragmented parts[1] string and is not accessible as a structured field.
Step 2 — get_business_details_and_phone is called, but with a fabricated ID:
// Tool input
{ "business_id": "0" }
// Tool output
{ "id": "", "is_error": true }
// Widget: state: null, responseMetadata: null, externalCallTimeMs: null
The model then reports to the user that “details are not available”, even though the business exists and the MCP server is fully functional.
Reference conversations
Working conversation (no parsing issue, correct chaining):
6a047239-bcd8-8329-9428-4de80f2b6120
Broken conversation (exhibits the bug described above):
6a217530-c564-8330-a376-e96a2475e3e2
6a217136-ff08-8329-ac93-7ae94c22a12a
Same MCP server, same query — the two conversations can be compared directly.
Key evidence: same MCP server works correctly on Claude
I tested the exact same query (search_businessesId_by_name, who: "Domaine de Locguénolé", location: "Kervignac") via Claude, which also connects to this MCP server.
Claude receives the tool result as plain JSON — no multimodal_text wrapping, no parts[], no citation markers:
{
"total_count": 1,
"results_returned": 1,
"results": [{
"id": "00257381",
"name": "Domaine de Locguénolé",
"address": "Route de Port Louis Le Hingair 56700 Kervignac",
"main_activity": "restaurants",
"permanently_closed": false
}]
}
Claude correctly extracts id: "00257381" and chains immediately to get_business_details_and_phone, returning the full business profile.
The MCP server applies no differentiation between clients — the response format is identical on the wire. The multimodal_text wrapping is introduced by ChatGPT.
Root cause hypothesis
ChatGPT appears to route some MCP tool results through its internal citation/grounding pipeline (typically used for web search or file retrieval). This pipeline:
- Wraps the response in
{ content_type: "multimodal_text", parts: [...] } - Fragments the JSON content into line-indexed strings
[L1],[L2]… - Injects a citation marker
@filecite@turnXfileY@
This makes the structured data opaque to the model. It cannot extract named fields (like id), substitutes a default value ("0"), and proceeds — resulting in a server-side error.
Note: search_businesses (different tool, same server) does not trigger this wrapping and works correctly. The difference may lie in how each tool’s response schema is interpreted by the pipeline.
Side note: this behavior started appearing after the fix deployed for the issue tracked in REGRESSION: Free ChatGPT accounts unable to invoke apps! - #29 by reagent-brian — not sure if it’s related, but worth mentioning in case the fix introduced a side effect on tool result handling.