Codex App rejects valid MCP resource_link tool results with "Unexpected response type"

Open
#33,404 0 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
4/5
Estimated time
3-5 days
Newbie friendliness
68/100
Issue type
Bug
Clarity
Mostly clear
Activity status
Quiet
Tech stack
rust
Domain
api, backend

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

app bug mcp tool-calls windows-os
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/call exits normally and the server writes zero bytes to stderr.
  • The tool's advertised outputSchema validates its structuredContent.
  • The exact live JSON-RPC response containing text,resource_link was deserialized separately with rmcp 1.8.0 (the version used by Codex runtime 0.144.2) and classified as ServerResult::CallToolResult, not CustomResult.
  • 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?
  1. Configure a local stdio MCP server in Codex App.
  2. 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 }
  }
}
  1. Open a new Codex App task so the tool is discovered.
  2. Invoke the tool.
  3. Observe Unexpected response type.
  4. Remove only the resource_link item, leaving the text block and structuredContent unchanged.
  5. Invoke the tool again and observe that it succeeds.

The public real-world handler that produced the confirmed A/B result is here:

https://github.com/rubicoul/mailru-codex-plugin/blob/400e7c51d9db20ba059daaed09726f6b44198776/plugins/mailru/src/core.ts

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
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 under rmcp 1.8.0 as CallToolResult, and the trigger is adding resource_link.
    https://github.com/openai/codex/issues/29002
  • #10334 concerns MCP content[] handling when structuredContent is present, but the reported tool call succeeds rather than failing with Unexpected 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:

  1. content: [text] succeeds.
  2. content: [text, resource_link] also succeeds.
  3. The resource_link survives the app-server/tool-result bridge or is deliberately downgraded without failing the call.
  4. 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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from openai/codex

All issues in openai/codex

Similar issues

More Rust issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.