Investigation & report by Claude Opus 4.8 (GitHub Copilot), 2026-06-11.
ARCHIVED REPO - problem solved 2026-06-12 (see community.openai.com - Bug/Regression - MCP tool result wrapped as multimodal_text)
- The
geocodeMCP tool works correctly. Over HTTP it returns a spec-compliant JSON-RPC response: acontent[]text block containing valid JSON and astructuredContentobject matching the declaredoutputSchema, withisError: false. - The bug is on the ChatGPT side. ChatGPT's MCP connector wraps the perfectly
valid tool output into a
multimodal_text/ citation block with emptydisplay_url/display_title, then truncates the actual content ([L1] { [L2] ... [L3]). - The fields
display_urlanddisplay_titleshown in ChatGPT's broken output do not exist anywhere in the server response — they are injected by ChatGPT. - Conclusion: nothing to fix on the geocontext server; this is a ChatGPT MCP client regression that should be reported to OpenAI.
The geocontext MCP server is deployed over HTTP at:
https://geollm.beta.ign.fr/geocontext/mcp
Recently, ChatGPT stopped displaying the result of geocode tool calls. For the input:
text: "Mairie de Loray"
maximumResponses: 1
ChatGPT renders this instead of the result:
content_type: "multimodal_text"
parts: Array(2)
0:"Citation Marker: fileciteturn0file0 "
1:"[L1] { [L2] ... [L3] "display_url": "", [L4] "display_title": """
The original prompt is preserved in PROMPT.md.
test_geocode_mcp.py is a self-contained MCP Streamable HTTP client (no SDK) that:
- Opens an MCP session —
initializethennotifications/initialized. - Fetches the
geocodetool definition (inputSchema,outputSchema,annotations). - Calls
geocodeacross a battery of cases:- the exact ChatGPT bug case (
Mairie de Loray,max=1), - multiple results,
max=10, defaultmaximumResponses, - precise address, accented characters, and a no-result query.
- the exact ChatGPT bug case (
- Dissects each raw JSON-RPC response:
content[]blocks, whether the text is valid JSON, presence ofstructuredContent,isError,_meta. - Scans every response for the citation fields ChatGPT relies on
(
display_url,display_title,url,title).
It handles both plain application/json and SSE (text/event-stream) responses,
which is what real MCP clients (including ChatGPT) negotiate.
# create env + install dependency (uv)
uv venv --python 3.12
uv pip install httpx
# run the test (full output saved to test_output.txt)
.venv\Scripts\python.exe test_geocode_mcp.py --no-color | Tee-Object -FilePath test_output.txtFull captured run: test_output.txt.
For the exact failing case (text="Mairie de Loray", maximumResponses=1), the
server returns:
{
"result": {
"content": [
{
"type": "text",
"text": "{\"results\":[{\"lon\":6.497148,\"lat\":47.153263,\"fulltext\":\"Mairie de Loray, 25390 Loray\",\"kind\":\"mairie\",\"city\":\"Loray\",\"zipcode\":\"25390\"}]}"
}
],
"structuredContent": {
"results": [
{
"lon": 6.497148,
"lat": 47.153263,
"fulltext": "Mairie de Loray, 25390 Loray",
"kind": "mairie",
"city": "Loray",
"zipcode": "25390"
}
]
}
},
"jsonrpc": "2.0",
"id": 3
}This is exactly what the MCP specification (protocol 2025-06-18) expects:
- a human/text representation in
content[], and - a machine representation in
structuredContentvalidating against the tool's declaredoutputSchema.
| Check | Result |
|---|---|
| Server | geocontext 0.9.8 |
| Negotiated protocol | 2025-06-18 |
outputSchema declared |
YES |
structuredContent returned |
YES |
content[].text is valid JSON |
YES |
isError |
false for every case |
| HTTP / JSON-RPC errors | none |
All 7 test cases (single result, multiple, max=10, default, precise address,
accented input Besançon, and a no-result query) behaved identically and correctly.
The script explicitly scans every response for the fields ChatGPT shows:
Looking for ChatGPT citation fields (display_url/display_title)
display_url : absent
display_title : absent
url : absent
title : absent
These fields are absent from the server payload in every single case. They appear only in ChatGPT's rendered output, which proves they are injected by ChatGPT's MCP connector — not produced by the geocontext server.
ChatGPT is routing this generic tool result through its citation / "document"
rendering pipeline (the one designed for search/fetch connectors that return
documents carrying url / title / display_url / display_title). Because
geocode is an ordinary tool with no such display metadata, ChatGPT:
- builds a citable "document" with empty
display_url/display_title, and - truncates the real payload to
[L1] { [L2] ... [L3],
effectively swallowing the result the user asked for.
- geocontext MCP side: no issue. The server is spec-compliant and returns
both
contenttext (valid JSON) and a validstructuredContent. - ChatGPT side: regression to report to OpenAI — the MCP connector wraps a
valid, non-document tool result in a
multimodal_textcitation block with emptydisplay_url/display_titleand truncates the content, instead of displaying the structured/text result.
- Server response is MCP-compliant (
2025-06-18):contenttext + validstructuredContent,isError=false, nourl/title/display_*fields. - ChatGPT wraps it as
multimodal_textwithCitation Marker/fileciteturn0file0and emptydisplay_url/display_title. - The real content is truncated (
[L1]…[L3]) instead of being displayed/used. - Reproducible with
geocode(text="Mairie de Loray", maximumResponses=1)againsthttps://geollm.beta.ign.fr/geocontext/mcp.