Remote get_tool_result completes, but the Chat-visible result contains only async_call metadata · Issue #845 · wonderwhy-er/DesktopCommanderMCP · GitHub
Skip to content

Remote get_tool_result completes, but the Chat-visible result contains only async_call metadata #845

Open

Description

@Morrunlol

Observed behavior

On 2026-10-13, an existing Chat used Remote Desktop Commander to read an authorized local text file. The call returned running with a call_id. The same Chat performed its first get_tool_result and received completed metadata only. It reported no text, content blocks, result body, truncation notice, or response-resource reference. It stopped immediately; the read was not repeated and no downstream business command was submitted.

The original Chat was the only result receiver assigned by us. The coordinating Codex instance did not retrieve that call. This excludes our coordinator retrieving first as a cause in this attempt; it does not audit other platform consumers.

The local device reports version 0.2.51 and has existing local transport/permission customizations. We have not established which deployed cloud handler or Chat adapter version constructs this result.

Useful field differential, with limits

An earlier, different diagnostic received by Codex exposed a full MCP result shaped like the synthetic example below. Its text was in content, while structuredContent contained async_call metadata. The latest Chat-visible response has the same field structure as that structuredContent subobject. These were different calls and file sizes, so this is a lead, not proof that the latest raw response contained a body or that a particular component dropped it.

Synthetic structural example — not the latest call's network capture:

{
"content": [{"type": "text", "text": "OFFLINE_TEXT_BODY"}],
"structuredContent": {
"async_call": {
"call_id": "00000000-0000-4000-8000-000000000001",
"tool_name": "read_file",
"status": "completed",
"retry_original": false
}
},
"isError": false
}

Observed model-visible shape, with identifying values removed:

{
"async_call": {
"call_id": "",
"tool_name": "read_file",
"status": "completed",
"device_id": "",
"created_at": "",
"completed_at": "",
"retry_original": false
}
}

What has been checked

  • The installed @modelcontextprotocol/sdk 1.29.0 CallToolResultSchema and Client.callTool preserve both content and structuredContent in a synthetic offline test. Its request transport was a local stub; this is not a cloud-handler or Chat-adapter test.
  • A separate synchronous Chat read returned complete text. Its smaller input and different call make it an imperfect control.
  • The Chat record preserves all model-visible messages, not raw network RPC. The exact wall-clock time of the get invocation is not independently available.
  • No service, credentials, installed SDK, or production tool implementation was changed for this diagnosis. No stopped call has been replayed.

Requested investigation

Please identify the existing cloud get_tool_result terminal-result builder and the connector/Chat output adapter, or provide their non-sensitive output contract:

  1. When status is completed, where is the original tool's content placed? Is structuredContent merged with async_call or replaced?
  2. Does any adapter choose structuredContent instead of retaining sibling content? What outputSchema is declared?
  3. Can retention remove the result body while completed metadata remains available? What are the deployed rules?
  4. Which component owns the raw MCP-to-model-visible conversion for this integration?

Acceptance for a targeted fix

  • Preserve the original readable body and appropriate status/error fields through the existing result path. If content contains existing resource or non-text blocks, preserve their supported representation rather than inventing text.
  • Do not expose hidden _meta or credentials while fixing visible fields.
  • A metadata-only completed read must remain distinguishable from a successfully recovered body. Failed, expired and unknown cases must not be upgraded to success.
  • Regression-check a full content-plus-structured result, a metadata-only negative case and a synchronous text result. Any later live verification needs a separately bounded original-caller-only attempt; this report does not request retries of the stopped call.

Reference: https://developers.openai.com/plugins/reference#tool-results
The documented result contract allows both content and structuredContent to be surfaced. It does not establish which deployed layer caused this incident.

Privacy: This draft contains no local paths, business text, user/account identifiers, live call/device identifiers, authentication material, or original Kernel content. No production logs or conversation exports are attached.

Activity

  1. akzyzop commented on Oct 13, 2026

    @akzyzop

    Draft comment for DesktopCommanderMCP #845 — not posted

    Same-call evidence: stored content and direct MCP content survive; ChatGPT receives metadata only

    On 13 October 2026, a bounded loopback fixture served one GET and returned a fixed, non-sensitive 37-byte text after about six seconds. The original Remote read_file was invoked once. It returned running, and the original ChatGPT web conversation then requested its result.

    For the SAME call, in this order:

    1. ChatGPT's first get_tool_result exposed completed async_call metadata only, without the text.
    2. An authorized exact-call/exact-device stored-result read returned one completed record containing the original content.
    3. A separate direct MCP client retrieved get_tool_result for that call. Its successful JSON-RPC reply contained sibling content and structuredContent. The full text was in content; structuredContent contained async_call only.
    4. A second get_tool_result through the ChatGPT connector again exposed only that same async_call object.

    The stored content and direct MCP content match. The model-visible object matches the direct reply's structuredContent. The original fixture received one GET and terminated; no original tool was replayed. This excludes large-result truncation and loss during execution/storage for this particular test. The direct retrieval happened after the first ChatGPT retrieval, so it cannot explain the first missing body by consuming it first.

    Important limitation: the direct request used an existing device session and a separate diagnostic client. It was NOT a capture of ChatGPT's own authenticated HTTP transaction. The evidence distinguishes the two result paths but does not yet separate a connector-side projection from a client/auth-context-dependent cloud builder. The deployed cloud/adapter version remains unknown. The local device agent has existing delivery-retry and logging customizations; this is not represented as a pristine installation.

    Source lead, not proof of shared deployment

    OpenAI's documented tool-result contract says both content and structuredContent are surfaced to the model:
    https://developers.openai.com/plugins/reference#tool-results

    Related reports:

    In the published Codex rust-v0.147.0 source, CallToolResult::as_function_call_output_payload has a non-null structured_content branch that returns before the ordinary content fallback for non-encrypted results. The source was checked, rather than inferred only from the report:
    https://github.com/openai/codex/blob/rust-v0.147.0/codex-rs/protocol/src/models.rs
    Git blob: 2c2a6d6b7aa49eee6309e5a9ba9e7587a1047d4e.
    This is a concrete implementation lead, NOT evidence that ChatGPT uses this function or release.

    Requested targeted correction

    Please identify the hosted terminal-result builder and the model-facing result projection, then preserve original visible content alongside async_call metadata in that existing path. Please keep legitimate structured-only tools working; this report concerns a read whose known nonempty body disappeared. Preserve failures, unknown outcomes and supported visible resource blocks; do not expose hidden metadata or require re-execution of a side-effecting tool to regain its output.

    A focused acceptance should show the same nonempty text through the model-facing result path, preserve the metadata, preserve an actual tool error, and distinguish a genuinely missing read body from a recovered body. No new scheduler, device service, database schema, additional authorization or permission widening is requested.

    This comment contains no live call/device identifiers, local paths, business content, credentials, production logs or conversation exports. It does not attach the private evidence bundle.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions