[Bug/Regression] MCP tool result wrapped as `multimodal_text` + `parts[]` — model cannot extract structured data, chained tool call fails with fabricated ID

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 IDs
  • search_businesses — searches by activity/category, returns a structured JSON list
  • get_business_details_and_phone — fetches full details for a given business_id

The expected flow for a named-entity query (e.g. “give me all info on Domaine de Locguénolé in Kervignac”) is:

  1. search_businessesId_by_name → returns { id: "00257381", name: "Domaine de Locguénolé", ... }
  2. 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:

  1. Wraps the response in { content_type: "multimodal_text", parts: [...] }
  2. Fragments the JSON content into line-indexed strings [L1], [L2]
  3. 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.

Thanks for reporting. Bumping for visibility.