Skip to content

feat(mcp): show loading pill and gate tool dispatch on readiness#687

Merged
esengine merged 1 commit into
esengine:mainfrom
dimasd-angga:fix/issue-638-mcp-background-load-polish-visible-loadi
May 12, 2026
Merged

feat(mcp): show loading pill and gate tool dispatch on readiness#687
esengine merged 1 commit into
esengine:mainfrom
dimasd-angga:fix/issue-638-mcp-background-load-polish-visible-loadi

Conversation

@dimasd-angga

Copy link
Copy Markdown

Summary

Tool calls dispatched while an MCP server is still handshaking were surfacing transport errors because the bridge had no signal that the connection wasn't ready yet. This adds a per-server readiness gate that dispatches await (capped at 30s) before invoking live.callTool, plus a status-bar pill so the otherwise-invisible background load is legible to the user.

Changes

  • src/cli/commands/chat.tsx: track a per-server ready deferred in createMcpRuntime, resolve it on the connected lifecycle event, and reject it on disabled / failed so awaiting dispatches fail fast with a meaningful reason. Pass ready through to bridgeMcpTools.
  • src/mcp/registry.ts: extend BridgeOptions / BridgeEnv with ready, readyTimeoutMs, and serverName. Add a waitForReady helper that races the readiness promise against the timeout and the call's AbortSignal, and await it at the top of every bridged callTool closure. Default timeout is DEFAULT_READY_TIMEOUT_MS (30_000ms).
  • src/cli/ui/App.tsx: dispatch a mcp.loading event from the lifecycle sink — initialised at { ready: 0, total: specs.length }, bumped on connected / disabled / failed so the pill clears once every server reaches a terminal state.
  • src/cli/ui/state/events.ts, src/cli/ui/state/reducer.ts, src/cli/ui/state/state.ts: add the mcp.loading action, its zod schema, and an mcpLoading?: { ready, total } field on StatusBar. The reducer drops the field when total <= 0 and short-circuits no-op updates.
  • src/cli/ui/layout/StatusRow.tsx: render a ⌁ MCP n/m pill (new McpLoadingPill component) only while ready < total.
  • src/i18n/EN.ts, src/i18n/zh-CN.ts, src/i18n/types.ts: add the statusBar.mcpLoading translation key ("MCP" in both locales) with a JSDoc note describing the rendered format.

Testing

  • npm test -- tests/mcp/registry-readiness.test.ts — covers a callTool invoked mid-handshake resolving once the readiness deferred settles.

Notes

  • The 30s cap matches the value called out in the issue body and is exposed as readyTimeoutMs on BridgeOptions for callers that want to override it.
  • ready.catch(() => undefined) is attached at construction so a server that fails before any tool is invoked doesn't trigger an unhandled rejection.
  • The pill only renders while ready < total; once every server reaches connected / disabled / failed it disappears, so there's no separate teardown event to manage.

Closes #638

Tool calls invoked during MCP handshake were surfacing transport errors because the bridge had no signal that the server was still connecting. A per-server readiness deferred lets dispatches wait (capped at 30s) instead of failing, and a status-bar pill makes the otherwise-invisible background load legible to the user.
@esengine esengine merged commit c07739e into esengine:main May 12, 2026
3 checks passed
esengine added a commit that referenced this pull request May 12, 2026
…il, CardStream fix (#705)

npm-only release. The Tauri desktop source is in the repo and the CLI
subcommand works, but installer bundles for macOS / Windows / Linux
don't ship this round (separate release once signing's settled).

Highlights:
- Tauri desktop client with multi-tab concurrent runtimes (#689)
  plus a near-full polish pass: wallet balance, version chip, active-
  plan rail, abortable pause-gates, edit-gate pill, en + zh-CN i18n,
  shared pause-policy module dedup'd with the CLI TUI (#701)
- checkpoint API + git-changes panel in the embedded dashboard (#682)
- outside-sandbox file access approval modal (#696)
- MCP loading pill + readiness gate on tool dispatch (#687)
- escalate-after flag for flash → pro threshold (#699)

Fixes:
- CardStream Maximum-update-depth crash, quantize window so boundary
  cards stop oscillating (#700, #702)
- `reasonix code` bridges config key to env + lazy subagent client so
  fresh installs can reach the setup wizard (#703)
- pinned-mode scroll shrinks coalesced (#666), generic CSI key decode
  (#692), shell-confirm preview clamp (#691), frontmatter BOM/folded
  lines (#690), MCP error classification (#688), and more
ChasLui pushed a commit to ChasLui/DeepSeek-Reasonix that referenced this pull request May 23, 2026
…ngine#687)

Tool calls invoked during MCP handshake were surfacing transport errors because the bridge had no signal that the server was still connecting. A per-server readiness deferred lets dispatches wait (capped at 30s) instead of failing, and a status-bar pill makes the otherwise-invisible background load legible to the user.
ChasLui pushed a commit to ChasLui/DeepSeek-Reasonix that referenced this pull request May 23, 2026
…il, CardStream fix (esengine#705)

npm-only release. The Tauri desktop source is in the repo and the CLI
subcommand works, but installer bundles for macOS / Windows / Linux
don't ship this round (separate release once signing's settled).

Highlights:
- Tauri desktop client with multi-tab concurrent runtimes (esengine#689)
  plus a near-full polish pass: wallet balance, version chip, active-
  plan rail, abortable pause-gates, edit-gate pill, en + zh-CN i18n,
  shared pause-policy module dedup'd with the CLI TUI (esengine#701)
- checkpoint API + git-changes panel in the embedded dashboard (esengine#682)
- outside-sandbox file access approval modal (esengine#696)
- MCP loading pill + readiness gate on tool dispatch (esengine#687)
- escalate-after flag for flash → pro threshold (esengine#699)

Fixes:
- CardStream Maximum-update-depth crash, quantize window so boundary
  cards stop oscillating (esengine#700, esengine#702)
- `reasonix code` bridges config key to env + lazy subagent client so
  fresh installs can reach the setup wizard (esengine#703)
- pinned-mode scroll shrinks coalesced (esengine#666), generic CSI key decode
  (esengine#692), shell-confirm preview clamp (esengine#691), frontmatter BOM/folded
  lines (esengine#690), MCP error classification (esengine#688), and more
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

MCP background-load polish: visible loading indicator + dispatch-time wait

2 participants