Codex App rejects valid MCP resource_link tool results with "Unexpected response type"
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.