Summary
When Quinn (Copilot) proposes a connector tool call and a teammate approves it, the call executes, but its result goes nowhere: it is not added to the assistant's thread, and it is not rendered on the card either. The assistant then believes the action is still awaiting approval.
The data is fetched from the remote MCP server and effectively discarded — nobody, neither the model nor the human, ever sees it.
Environment
- Self-hosted, single workspace,
v0.13.2-1017-g9d222efbf
- AI: OpenAI directly (
OPENAI_BASE_URL=https://api.openai.com/v1), AI_CHAT_MODEL=gpt-4.1-mini
- Connector: a remote MCP server (Plane's hosted MCP), auth mode
bearer
- Tool policies: group defaults
read: always, write: approval
Steps to reproduce
- Add an MCP connector whose tools are classified as write (no
readOnlyHint), so they fall under write: approval.
- Open a conversation, switch the right-hand panel to Copilot.
- Ask something that requires the connector, e.g. "What is the title and status of work item ABC-107?"
- Quinn answers that the request has been submitted and needs approval, and renders the proposed-action card with the tool name and arguments. This part works correctly.
- Click Approve.
- The card changes to "Approved and executed". The connector row's
last_call_at is updated, so the call really did run.
- Ask a follow-up in the same Copilot chat: "Now tell me the title and status from the result, without a new lookup."
Expected
Quinn answers using the result of the approved call.
Actual
Quinn answers (translated): "The retrieval of the data for work item ABC-107 has not been approved yet, so I do not have the title and status."
At that point the action had been approved and executed twice. The card never shows the payload either — only a short status line.
Where this seems to come from
I did not chase this all the way, so take the pointers as observations rather than a diagnosis:
copilot-panel.tsx → runTurn notes that "History rides the AG-UI thread natively (useChat re-sends its accumulated messages)". The executed action's result is not part of those messages, so the next turn cannot see it.
copilot-proposed-action-card.tsx renders formatProposedActionResult(data.result) — explicitly documented as "a short, human line out of a tool's JSON result, if it offered one", falling back to "Approved and executed". A connector result ({ ok, data, note }) offers no such line, so the payload is never displayed.
So the result appears to be persisted on the proposed action server-side, but there is no path from there back into either the thread or the UI.
Impact
Any connector tool behind approval is effectively write-only: it can perform an action, but it cannot answer a question.
This is worse than it sounds for read-shaped tools. Many MCP servers bundle read and write into one tool — Plane's workitem handles list, retrieve, create and update in a single tool and therefore reports no readOnlyHint, so it lands in the write group and requires approval. Every lookup then goes through this path and every lookup loses its answer.
Side observation
retrieve without a field filter returns the full record (description HTML included) and hits CONNECTOR_RESPONSE_CHAR_LIMIT; the card shows "Result was truncated." Asking the assistant to limit the fields works around it. Mentioning it only because it is easy to mistake for the same bug — it is not.
Summary
When Quinn (Copilot) proposes a connector tool call and a teammate approves it, the call executes, but its result goes nowhere: it is not added to the assistant's thread, and it is not rendered on the card either. The assistant then believes the action is still awaiting approval.
The data is fetched from the remote MCP server and effectively discarded — nobody, neither the model nor the human, ever sees it.
Environment
v0.13.2-1017-g9d222efbfOPENAI_BASE_URL=https://api.openai.com/v1),AI_CHAT_MODEL=gpt-4.1-minibearerread: always,write: approvalSteps to reproduce
readOnlyHint), so they fall underwrite: approval.last_call_atis updated, so the call really did run.Expected
Quinn answers using the result of the approved call.
Actual
Quinn answers (translated): "The retrieval of the data for work item ABC-107 has not been approved yet, so I do not have the title and status."
At that point the action had been approved and executed twice. The card never shows the payload either — only a short status line.
Where this seems to come from
I did not chase this all the way, so take the pointers as observations rather than a diagnosis:
copilot-panel.tsx→runTurnnotes that "History rides the AG-UI thread natively (useChat re-sends its accumulated messages)". The executed action's result is not part of those messages, so the next turn cannot see it.copilot-proposed-action-card.tsxrendersformatProposedActionResult(data.result)— explicitly documented as "a short, human line out of a tool's JSON result, if it offered one", falling back to"Approved and executed". A connector result ({ ok, data, note }) offers no such line, so the payload is never displayed.So the result appears to be persisted on the proposed action server-side, but there is no path from there back into either the thread or the UI.
Impact
Any connector tool behind
approvalis effectively write-only: it can perform an action, but it cannot answer a question.This is worse than it sounds for read-shaped tools. Many MCP servers bundle read and write into one tool — Plane's
workitemhandleslist,retrieve,createandupdatein a single tool and therefore reports noreadOnlyHint, so it lands in the write group and requires approval. Every lookup then goes through this path and every lookup loses its answer.Side observation
retrievewithout a field filter returns the full record (description HTML included) and hitsCONNECTOR_RESPONSE_CHAR_LIMIT; the card shows "Result was truncated." Asking the assistant to limit the fields works around it. Mentioning it only because it is easy to mistake for the same bug — it is not.