Repository navigation
[FEATURE]: Progress indicator for MCP calls #26328
Description
Feature hasn't been suggested before.
- I have verified this feature I'm about to request hasn't been suggested before. ← Note: suggested but abandoned, see section Prior art
Describe the enhancement you want to request
Motivation
While an MCP call is running, OpenCode’s TUI currently doesn’t show progress info, even if the MCP server sends progress updates.
Especially with longer-running services (which are common in MCP, e.g. on-demand embedding runs), this is awkward from the user’s point of view because the conversation can seem stuck for minutes. That effect is about to get even more noticeable when #24964 is merged, which (correctly) fixes an issue with resetTimeoutOnProgress, causing the “user is waiting for anything to happen” time to become potentially unbounded.
Suggestion
If an MCP server sends progress messages, then the text in the TUI should reflect that progress message.
Depending of whether the MCP progress message includes the optional total and message fields, I suggest that instead of the current message:
⚙ mcp_service_name [query=very long running call]
I suggest that the TUI render one of the following:
⚙ mcp_service_name [query=very long running call] · In progress [42]
or, if the server includes a total:
⚙ mcp_service_name [query=very long running call] · In progress [42/800]
or, if the server includes both a total and a custom message:
⚙ mcp_service_name [query=very long running call] · Calculating embeddings [42/800]
Prior art
Here’s what has been done so far:
- @fahreddinozcan’s PR #24964 ← this is the foundation that actually triggers the MCP server to send progress messages (and fixes the timeout issue). Needs to be merged first.
- @wangguodong-f’s report [FEATURE]:Show progress bar for Subagent #22153 ← related but different focus (subagents). Pinging them anyway for ideas and to keep them in the loop.
Related but abandoned:
- @rfhold’s report #11821 ← very related, also abandoned. A bit more focused (it mentions only the SDK plumbing, not the TUI changes.) However, doing both plumbing and TUI at once might give the user more immediate value (and the developer a closer feedback loop).
- @xhuw’s report #2101 ← very similar to this report, abandoned
- @CagierAsh123’s report #5472 ← related but broader (not just focused on MCP), abandoned
- @ravshansbox’s report #3742 ← related but broader, abandoned
- @Becktor’s report feat(tui): show running tools and LLM status in sidebar #9655 ← related, different proposal (sidebar), broader, abandoned
Technical design (draft/proposal)
Note: I started out entirely unfamiliar with the code base, and there’s no way I could have possibly come up with a design draft by myself. The following is the gist of a few days of back-and-forth with Opus 4.7 and includes insights from a PoC implementation.
Design draft
MCP client
Accepts a new optional onProgress callback and passes that to the MCP SDK’s callTool options. If none is supplied, passes an empty callback (that same empty callback as in PR #24964, which tickles the MCP SDK to include a progress token in the request so the server can send progress messages and the timeout is properly reset.)
Session runner (prompt.ts)
Gets to own a small adapter (in form of an onProgress callback) that it injects into the MCP client. The adapter consumes progress reports and converts them into a v1 bus event and a v2 sync event (dual-write, just like the rest of the codebase does).
Bus
Needs a new v1 event type .tool.progress.report.
v2 sync-event registry
Gets a new v2 event type .next.tool.progress.report. A similar event type named .next.tool.progress already exists but handles unrelated stuff, i.e. partial tool output, which arrives entirely separate from progress reports. We can’t rename the existing ….progress type lest we’d break existing consumers. Hence, ….progress.report.
Session projector
Receives the progress report as a v2 sync event, updates the database, and updates the ToolStateRunning model in the v2 SessionMessage.
TUI v1 client
Receives the progress report from the bus and updates its store.part[messageID][idx].state.progress.
TUI v2 client
Receives the progress report from the bus and updates the ToolStateRunning model.
TUI v1/v2 renderer
Presents the progress info in its InlineTool and BlockTool components when a tool is running.
Commitment
If the core team decides that this is worth doing, I’ll be happy to implement this end to end.
Activity
claui commentedon May 28, 2026
Adding @chrislazar25 to the loop, who expressed they're willing to contribute to this feature.
onprogresstocallTool, so progress notifications can't extend the request timeout #28186 as a duplicate of this issueclaui commentedon Jun 18, 2026
@rekram1-node According to
CONTRIBUTING.md, I'm supposed to wait for feedback from the core team before I'm allowed to file a PR that touches UX. Is that rule still in effect? Can you help me figure out whom to contact for feedback?github-actions commentedon Aug 18, 2026
To stay organized issues are automatically closed after 60 days of no activity. If the issue is still relevant please open a new one.