ChatGPT MCP file reads return empty objects across Gitea and Nextcloud integrations

Hi everyone,

We’re experiencing a sudden regression with a custom Gitea MCP integration in ChatGPT, affecting two separate ChatGPT accounts.

The integration worked previously, but since October 15, 2026, the get_file_contents tool systematically returns {} to ChatGPT for existing, non-empty files.

Environment

  • ChatGPT Web with a custom MCP plugin

  • Gitea MCP Server 1.8.1

  • Gitea 28.1.0

  • OAuth authentication between ChatGPT and the MCP server

  • Token authentication between the MCP server and Gitea

What works

The same ChatGPT connection successfully executes get_me, get_repository_tree, list_commits, issue_read, pull_request_read, and other tools.

What fails

Calling get_file_contents with:

{
  "owner": "ORG",
  "repo": "REPO",
  "ref": "main",
  "path": "README.md"
}

The tool result exposed to the assistant is:

{}

This also happens with start_line, end_line, and withLines parameters, and with files in different repositories.

Requests for nonexistent files return proper errors.

Controlled server-side test

We invoked the same MCP 1.8.1 executable independently over JSON-RPC stdio with valid Gitea authentication.

Results:

  • get_me: successful, 241-character response

  • get_file_contents: successful, 4,445-character response

  • isError: false

  • No JSON-RPC error

This confirms that the MCP can retrieve the file, but does not yet establish whether the HTTP transport returns the same data.

Already attempted

  • Refreshing the ChatGPT integration configuration

  • Recreating the custom plugin and reconnecting OAuth

  • Updating the Gitea and MCP server versions

  • Testing multiple existing files and argument variants

No improvement.

There were no known MCP tool schema changes immediately before the regression.

Questions for the community

  1. Has anyone observed MCP text content being exposed as {} in ChatGPT while other tools work?

  2. Is there a known issue involving MCP content / structuredContent normalization or frozen tool snapshots?

  3. Has anyone found a reliable workaround that doesn’t require rebuilding the integration?

  4. Is there a way to determine whether the HTTP MCP response is being dropped before or after ChatGPT processes it?

This regression currently blocks our shared source-code development workflow across multiple ChatGPT assistants.

Any independent reproduction, workaround or engineering insight would be greatly appreciated.

Update — Same {} behavior reproduced with a second, independent MCP server (Nextcloud)

I have reproduced the same issue using a separate Nextcloud MCP integration in the same ChatGPT environment.

Nextcloud MCP test results:

Tool Result
nc_webdav_list_directory Works, lists files and metadata
nc_webdav_read_file Returns {} for existing Markdown files
collectives_get_collectives Works
collectives_get_pages Works
collectives_get_page Works, returns complete Markdown content (2,745 characters)

Two different existing Markdown files were tested with nc_webdav_read_file, both producing {} without a visible error. Directory listings confirmed their existence and nonzero sizes (890 and 2,873 bytes).

Potentially important difference in tool definitions:

When inspecting the exposed tool declarations in ChatGPT:

  • Gitea get_file_contents returns Promise<unknown>.

  • Nextcloud nc_webdav_read_file returns Promise<unknown>.

  • Nextcloud collectives_get_page has an explicit structured response schema, including a content string field.

The first two tools return {} while the third successfully exposes its complete content.

This suggests a possible correlation between loosely defined tool output schemas and result processing in ChatGPT.

However, this is not yet proof of a schema-related bug. The actual HTTP MCP responses have n

Hi Havgood,

I’m experiencing what appears to be the same issue with the official Linear MCP integration in ChatGPT.

The problem affects reading Linear documents, while other operations continue to work normally.

What works:

  • list_documents successfully retrieves document metadata and the beginning of the document content.

  • search successfully finds documents.

  • get_issue works correctly and can retrieve large issue descriptions, including an issue with a very extensive history.

What fails:

  • get_document consistently returns {} for existing, non-empty documents.

  • fetch also returns {} when attempting to retrieve those documents.

  • The issue affects both documents stored in the team’s Home section and documents associated with specific projects.

I tested multiple documents using their UUIDs and slugs, with the same results.

Interestingly, the Linear get_document and fetch tools are also declared as returning Promise<unknown>, matching the pattern you observed with Gitea and Nextcloud.

This seems consistent with your findings and may indicate a broader issue with how ChatGPT processes certain MCP tool responses, rather than a problem specific to one integration.

However, I haven’t independently verified the raw HTTP MCP responses, so I cannot confirm where the data is being lost.

I can confirm that the documents exist and are accessible through the Linear interface.

Hopefully, this additional reproduction helps narrow down the issue.

Thanks for documenting your findings!

Hi mk12,

Thanks for sharing your findings! Your reproduction with the official Linear MCP integration is particularly valuable, since it shows that this behavior is not limited to self-hosted Gitea or Nextcloud servers.

We’ve made some additional progress investigating the issue.

1. What we’ve confirmed

With Gitea MCP Server 1.8.1:

  • get_file_contents consistently returns {} in ChatGPT for existing files.

  • Repository trees, listings, issues and pull requests work normally.

  • Nonexistent-file requests return proper errors.

  • Direct authenticated JSON-RPC calls over stdio successfully return the file content (4,445 characters in our test).

With Nextcloud MCP:

  • nc_webdav_read_file returns {} for existing Markdown files.

  • nc_webdav_list_directory works.

  • collectives_get_page successfully returns complete Markdown content (2,745 characters in our test).

Interestingly, the affected Gitea and Nextcloud file-reading tools are also exposed as Promise<unknown>, just like the Linear tools you identified.

This correlation is worth investigating, although it does not establish that the tool’s declared return type causes the problem.

2. Independent HTTP reproduction and source investigation

Their findings include:

  • Successful direct MCP file retrieval over HTTP, not only stdio.

  • HTTP 200 responses containing valid MCP text content.

  • No structuredContent in the successful file-read response.

  • ChatGPT still exposing {} for equivalent file-read requests.

They also developed an experimental compatibility patch that preserves the original text response while adding the same data as structuredContent.

The patch has passed automated tests, but it has not yet been confirmed to solve the problem in a live ChatGPT connection.

Importantly, MCP supports text-only tool results. The absence of structuredContent is not itself a protocol violation.

3. Four-connector reproduction

We also created a dedicated ChatGPT conversation to compare four MCP integrations:

  • Gitea

  • Gitea alternative

  • Nextcloud

  • Nextcloud native

The purpose was to compare authentication, listings, successful file reads and error handling in a single diagnostic session.

4. What might help next

If you can determine whether Linear’s get_document and fetch return MCP text blocks, structured content, or another result representation, it would be particularly useful to compare that with Gitea’s behavior.

We have an open OpenAI Support case (#17440919), with reproduction timestamps and server-side diagnostics supplied for investigation.

The issue has now been reported across three independent MCP products: Gitea, Nextcloud and Linear.

This increasingly suggests a possible shared ChatGPT MCP result-handling regression, although the exact failure boundary is still unconfirmed.

Thanks again for contributing an independent reproduction. It significantly strengthens the investigation, and hopefully we can identify a reliable workaround together.

Hi Havgood,

Thank you for your detailed response and for continuing to investigate this issue.

I’ve now completed a controlled diagnostic investigation using the official Linear MCP integration in both ChatGPT and Codex. We have obtained some additional evidence that may be useful for your investigation and your existing OpenAI Support case.

1. Same document, different results

We created a dedicated test document in Linear containing exactly 50 characters and tested the same document ID in both environments.

In Codex:

  • list_documents returned the correct 50 characters.

  • await get_document returned the complete content.

  • The result exposed content, structuredContent, and isError properties.

  • The text content was available.

In ChatGPT:

  • list_documents returned the same correct 50 characters.

  • await get_document returned {}.

  • Reflect.ownKeys(result) returned [].

  • result.content, result.structuredContent, and result.isError were all undefined.

Both environments returned the same Linear user ID through get_user("me").

This rules out several explanations, including a missing await, ordinary JSON serialization hiding properties, an empty or nonexistent document, and document size being necessary to reproduce the failure.

However, matching user IDs do not necessarily mean both environments use the same OAuth grant or backend processing path.

2. Additional controlled tests

Codex successfully tested documents containing:

  • 20 characters

  • 100 characters

  • 500 characters

  • 501 characters

  • 2,001 characters

  • Czech Unicode text

  • Markdown formatting

  • Updated document content

Seven of the eight test variants matched exactly, including SHA-256 verification.

The only mismatch involved Markdown normalization: two - list markers were converted to *.

Codex also successfully retrieved three existing Linear documents containing:

  • 42,608 characters

  • 28,820 characters

  • 149,907 characters

In Codex, fetch and get_document returned matching document contents.

In ChatGPT, get_document continued to return {} for the same documents.

3. What we can confirm

The same Linear documents and account identity produce different results depending on the environment.

In the affected ChatGPT environment, the returned object is genuinely empty at the tool-result boundary accessible to our diagnostic code.

We still cannot determine whether the original MCP server response was already empty or whether its content was lost during transport or subsequent processing.

Therefore, our final root cause verdict is:

UNDETERMINED — reproducible failure, exact internal cause not yet established.

We have not modified OAuth permissions, MFA, YubiKey registrations, or security settings.

4. Possible relationship to your findings

Your independent Gitea tests are particularly interesting because you confirmed valid MCP text content being returned over HTTP, while ChatGPT still exposed {}.

Our Linear findings show a similar symptom with an official integration, but we cannot yet establish whether the underlying cause is identical.

Together, these observations strengthen the case for investigating a possible shared MCP result-handling regression in ChatGPT.

5. Could you help escalate these findings to OpenAI?

I noticed that you already have an open OpenAI Support case, #17440919, with diagnostic information and reproduction details.

Would you be willing to forward our Linear findings to OpenAI Support as additional evidence in that case?

If you happen to have another established or appropriate channel to reach the OpenAI engineering team, I would also be very grateful if you could share these findings there.

The most useful evidence is the controlled comparison of the same 50-character Linear document:

  • Codex successfully retrieves the complete content.

  • ChatGPT retrieves the same content through list_documents.

  • ChatGPT’s get_document returns an object with no own properties.

It would be particularly helpful if OpenAI could compare the original MCP response with the result exposed after connector processing for a failing request.

I completely understand that you may not have any direct access to the engineering team. Sharing the additional reproduction through your existing support case would already be greatly appreciated.

If OpenAI needs further diagnostic details, timestamps, or a sanitized reproduction report, I would be happy to provide them.

Thank you again for your work on this issue and for sharing your findings publicly. Your investigation has been extremely helpful in narrowing down the possible causes.

Best regards,
mk12

Confirmed in a live ChatGPT connector: adding structuredContent fixes it

Thanks @Havgood — your structuredContent compatibility patch works. We tested the same idea live in ChatGPT today (Oct 18) and can confirm it.

Setup: custom MCP server (C# MCP SDK 2.2.0, Streamable HTTP). read_file showed {} in ChatGPT for plain TXT files as well as DOCX and PDF; errors and other tools worked — the same pattern as above.

Change: for a successful file-read result we keep content[].text unchanged and also send the same JSON object as structuredContent:

json

{
  "content": [{ "type": "text", "text": "{\"ok\":true,\"path\":\"a.txt\",\"content\":\"1: hello\"}" }],
  "structuredContent": { "ok": true, "path": "a.txt", "content": "1: hello" },
  "isError": false
}

Result: ChatGPT reads TXT, DOCX and PDF files again.

Two details that matter:

  1. Put the full payload in structuredContent, including the file text — not a summary. Claude Code currently passes only structuredContent to the model when it is present (GitHub issue 55677 in the anthropics/claude-code repository). A summary there would hide the file content from Claude Code users.
  2. Keep the text block too. The MCP spec recommends it for clients that do not read structuredContent.

Cost: the response on the wire roughly doubles. Model tokens should not: in the thread “How ‘content’ and ‘structuredContent’ in the tool response is handed to the model” on this forum, ChatGPT was reported to give the model only structuredContent when it is present, and Claude Code does the same. So the model sees the file once.

This is a workaround for a ChatGPT-side regression; we will remove it once OpenAI fixes the issue.

Thanks for the confirmation and for testing the structuredContent workaround in a live ChatGPT connector!

I’ve forwarded your findings, including the working JSON example, to OpenAI Support under case #17440919.

I also shared the independent Linear/Codex comparison reported earlier in this thread, along with our Gitea and Nextcloud reproductions and a sanitized HAR capture.

I’ve explicitly asked Support to escalate the issue to the engineering team responsible for MCP tool-result processing.

The evidence is becoming quite compelling: multiple independent MCP implementations are affected, and we now have a confirmed workaround that restores functionality without changing the underlying file-reading logic.

Hopefully, this will help OpenAI identify and fix the regression rather than requiring every MCP server developer to implement a compatibility workaround.

Thanks again to everyone contributing to the investigation. I’ll share any meaningful updates from Support here.

Update to my Oct 18 reply: the structuredContent copy is no longer needed.

Credit goes to 0xMax42 and vdog284 in openai/tunnel-client issue 91. They found that ChatGPT shows {} when the tool result (a JSON text block) contains a field named “content”, and that renaming that field fixes it: 0xMax42 on Gitea MCP get_file_contents, vdog284 on their own read_file. Why ChatGPT drops it is still not confirmed; the workaround is.

I confirmed it on a third server, a C# MCP server (ModelContextProtocol C# SDK). read_file returned {“ok”:true,…,“content”:“”}. I renamed the field to “text” and removed the structuredContent copy:

  • ChatGPT web, Developer Mode, custom connector, Oct 22
  • .txt, .docx and .pdf files: all read correctly
  • Checked against the files: I asked for exact lines (1-3, the last line, line 10 of the PDF) and they matched
  • Checked the raw result: the model listed the fields as ok, path, totalLines, firstLine, lastLine, truncated, text, warning (no “content”, no structuredContent)

So if your tool returns JSON as text, avoid a key named “content” in it. Compared with adding structuredContent, the response carries the text once instead of twice and does not depend on how ChatGPT handles structuredContent.

It is still a ChatGPT-side regression (in this thread Codex read the same “content” result fine), so OpenAI should fix it. Until then, renaming the field is the simplest workaround.

If you control the MCP server, rename the field inside the JSON text from content to file_content or text. Keep the outer MCP content array and its text block as they are. That change let the Gitea and C# testers read their files again without adding a copy in structuredContent.

For anyone who can’t change their Gitea server, the same file read has also worked in ChatGPT Work.

Thank you for the information and for sharing the workaround.

Unfortunately, this does not help users who rely on official third-party MCP connectors, where we have no control over the server implementation or its response format.

I am experiencing this exact issue with the official Linear connector in ChatGPT.

As of October 28, 2026, the problem is still fully reproducible:

  • Searching for Linear documents works correctly.

  • Document IDs, titles, and metadata are returned correctly.

  • list_documents returns only the first 500 characters.

  • get_document consistently returns {}.

  • fetch consistently returns {}.

  • The issue affects both Linear Home documents and project documents.

  • The same documents can be read successfully through Codex, but not through ChatGPT.

We have also tested creating a completely new document containing only 1,000 random alphanumeric characters. The same problem occurs.

This strongly suggests that the issue may be related to how ChatGPT processes MCP tool responses rather than the documents themselves.

Since the problem has been reported across multiple independent MCP integrations, including Gitea, Nextcloud, and Linear, I would appreciate clarification on three points:

  1. Is OpenAI officially investigating this issue within ChatGPT’s MCP response handling?

  2. Is there a planned platform-level fix for users who cannot modify their MCP servers?

  3. Is there any supported workaround for official connectors such as Linear, other than switching to ChatGPT Work?

This functionality is essential to my workflow, and the regression has persisted since at least October 16, 2026.

Thank you for your attention. Any update from the engineering team would be greatly appreciated.