Codex App rejects valid MCP resource_link tool results with "Unexpected response type"
Nobody has claimed this yet.
Assessment
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Newbie friendliness
- 68/100
Research direction
Start with codex-rs/codex-mcp/src/connection_manager.rs and the existing RawContent::ResourceLink branch in codex-rs/tui/src/history_cell/mcp.rs. Add or run an end-to-end local stdio MCP test covering text-only and text-plus-resource_link results. Done means the latter completes successfully, preserves or deliberately downgrades the resource link, and unsupported responses identify the actual variant or content type.
Written by the indexing model from the issue text.
Description
What version of the Codex App are you using (From “About Codex” dialog)?
26.707.9981.0
Affected in-app session:
- Originator:
Codex Desktop - Embedded runtime:
0.144.2 - MCP transport: local
stdio
A standalone codex-cli 0.144.4 is also installed, but it was not used for the failing in-app tool call.
What subscription do you have?
ChatGPT Pro
What platform is your computer?
Microsoft Windows NT 10.0.26200.0 x64
Additional OS information: Windows 11 Pro 25H2, build 26200.8737, 64-bit.
What issue are you seeing?
Summary
Codex App successfully initializes a local stdio MCP server, discovers its tools, and accepts text-only tool results. However, the app rejects an otherwise valid tools/call result when content also contains the standard MCP content block type resource_link.
The user-visible error is:
tool call error: tool call failed for `<server>/<tool>`
Caused by:
Unexpected response type
The same server, tool, arguments, credentials, and structuredContent succeed when no result is returned and therefore no resource_link block is present. They also succeed through a direct MCP stdio client.
Controlled A/B result
| Result shape | Direct MCP stdio client | Codex App bridge |
|---|---|---|
content: [text] |
succeeds | succeeds |
content: [text, resource_link] |
succeeds | fails with Unexpected response type |
Additional controls:
- The direct
tools/callexits normally and the server writes zero bytes to stderr. - The tool's advertised
outputSchemavalidates itsstructuredContent. - The exact live JSON-RPC response containing
text,resource_linkwas deserialized separately withrmcp 1.8.0(the version used by Codex runtime0.144.2) and classified asServerResult::CallToolResult, notCustomResult. - No mailbox data or secret values are needed to reproduce the response-shape failure.
This points to the Codex App/local-plugin bridge after a valid MCP response is produced, rather than to authentication, transport, tool execution, or output-schema validation.
Impact
A local MCP plugin that follows the MCP spec and adds clickable resource_link content cannot reliably return successful tool results in Codex App. This can affect any MCP server emitting resource links, not only the server used to discover this issue.
What steps can reproduce the bug?
- Configure a local stdio MCP server in Codex App.
- Register a tool whose handler returns this result shape:
{
"content": [
{
"type": "text",
"text": "ok"
},
{
"type": "resource_link",
"uri": "https://example.com/",
"name": "Example",
"title": "Example",
"description": "Example resource",
"mimeType": "text/html",
"annotations": {
"audience": ["user"],
"priority": 0.8
}
}
],
"structuredContent": {
"ok": true,
"data": { "count": 1 }
}
}
- Open a new Codex App task so the tool is discovered.
- Invoke the tool.
- Observe
Unexpected response type. - Remove only the
resource_linkitem, leaving the text block andstructuredContentunchanged. - Invoke the tool again and observe that it succeeds.
The public real-world handler that produced the confirmed A/B result is here:
What is the expected behavior?
Codex App should accept a valid MCP CallToolResult containing resource_link blocks.
If a particular surface cannot render resource links, it should still complete the tool call and preserve, ignore, or safely convert that block while retaining the text and structuredContent. An unsupported optional presentation block should not fail the entire tool call.
Additional information
Protocol and implementation evidence
- Negotiated MCP protocol version:
2025-06-18. - Server SDK:
@modelcontextprotocol/sdk 1.29.0. - Codex runtime dependency:
rmcp 1.8.0. - The MCP specification includes
resource_linkas a valid tool-result content type:
https://modelcontextprotocol.io/specification/2025-06-18/server/tools - Codex's own TUI code already has a
RawContent::ResourceLinkrendering branch:
https://github.com/openai/codex/blob/main/codex-rs/tui/src/history_cell/mcp.rs - The affected runtime's MCP connection manager serializes parsed MCP content blocks into generic JSON values:
https://github.com/openai/codex/blob/rust-v0.144.2/codex-rs/codex-mcp/src/connection_manager.rs
Related issues searched
- #29002 reports the same generic error when a valid text result is decoded as
CustomResult. This report is distinct: the exact live response here decodes underrmcp 1.8.0asCallToolResult, and the trigger is addingresource_link.
https://github.com/openai/codex/issues/29002 - #10334 concerns MCP
content[]handling whenstructuredContentis present, but the reported tool call succeeds rather than failing withUnexpected response type.
https://github.com/openai/codex/issues/10334
No exact open or closed duplicate combining resource_link with Unexpected response type was found before filing.
Suggested regression coverage
Please add an end-to-end local stdio MCP test where:
content: [text]succeeds.content: [text, resource_link]also succeeds.- The
resource_linksurvives the app-server/tool-result bridge or is deliberately downgraded without failing the call. - Any genuinely unsupported response reports the actual unhandled variant/content type instead of only
Unexpected response type.
Privacy
The public report intentionally omits account addresses, message data, subjects, senders, OAuth credentials, tokens, client identifiers, local paths, and session/message identifiers. The reproduction uses only synthetic values.
- Dominant language
- Rust
- Stars
- 125k
- Forks
- 19.5k
- Avg merge
- 1m
- Merged PRs (30d)
- 1k
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from openai/codex
-
enhancement remote
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
-
bug CLI windows-os
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
-
macOS sandbox blocks hw.optional.arm64 sysctl, causing Flutter to misdetect Apple Silicon as x64 Openbug CLI sandbox
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
-
bug CLI TUI
Difficulty 2/5 1-3 hours Newbie friendliness 90/100
-
CLI config enhancement skills
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 86/100
kwakseongjae/auto-hwp#319 ·
-
area:cli bug filter-quality good first issue priority:medium
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
-
Difficulty 1/5 Under an hour Newbie friendliness 72/100
bevyengine/bevy#25861 ·
-
comp-datalake
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
ClickHouse/ClickHouse#121222 ·
-
A-linter
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
oxc-project/oxc#26863 ·