Background MCP loading shipped in #363's spirit — chatCommand no longer awaits server handshakes, and the TUI is interactive immediately (src/cli/commands/chat.tsx:505-508, src/cli/ui/App.tsx:863-907). Two follow-ups remain from the original ask:
1. Visible "loading" indicator in the status bar
Today lifecycle events (handshake / connected / failed / slow) are pushed as info cards into the chat log via log.pushInfo(...). That's easy to miss while the user is typing, and there's no at-a-glance answer to "are my MCP servers up yet?"
Proposed: a small status-bar pill rendered while any bridged server is mid-handshake — e.g. ⌁ MCP 2/3 next to the wallet pill, hidden once all configured servers are either connected or failed. Source the count from mcpRuntime.summaries() + the lifecycle sink already wired up in App.tsx.
2. Tool dispatch should await an unready server
src/mcp/registry.ts:63-88 calls await live.callTool(...) directly. If the model invokes a tool from a server whose handshake is still in flight, the transport error surfaces instead of the implicit "just wait" behavior #363 asked for.
Proposed: the bridged closure consults a per-server readiness promise; if the server is handshaking, await it (with a sensible timeout — 30s?) before dispatching. If the server already failed, surface the existing error.
Scope
- (1)
src/cli/ui/state/state.ts (add mcpLoading to StatusBar), src/cli/ui/state/reducer.ts (event → state), src/cli/ui/App.tsx (already has the lifecycle sink — push to state), src/cli/ui/layout/StatusRow.tsx (render). Small i18n string add.
- (2)
src/mcp/runtime.ts (or wherever the per-server lifecycle lives — track a ready deferred per spec), src/mcp/registry.ts (await it before callTool). One integration test that fires callTool mid-handshake and asserts it resolves rather than rejects.
Either gap is independently shippable — separate PRs welcome. Both are good-first-issue scope.
Background MCP loading shipped in #363's spirit —
chatCommandno longer awaits server handshakes, and the TUI is interactive immediately (src/cli/commands/chat.tsx:505-508,src/cli/ui/App.tsx:863-907). Two follow-ups remain from the original ask:1. Visible "loading" indicator in the status bar
Today lifecycle events (
handshake/connected/failed/slow) are pushed as info cards into the chat log vialog.pushInfo(...). That's easy to miss while the user is typing, and there's no at-a-glance answer to "are my MCP servers up yet?"Proposed: a small status-bar pill rendered while any bridged server is mid-handshake — e.g.
⌁ MCP 2/3next to the wallet pill, hidden once all configured servers are eitherconnectedorfailed. Source the count frommcpRuntime.summaries()+ the lifecycle sink already wired up inApp.tsx.2. Tool dispatch should await an unready server
src/mcp/registry.ts:63-88callsawait live.callTool(...)directly. If the model invokes a tool from a server whose handshake is still in flight, the transport error surfaces instead of the implicit "just wait" behavior #363 asked for.Proposed: the bridged closure consults a per-server readiness promise; if the server is
handshaking, await it (with a sensible timeout — 30s?) before dispatching. If the server alreadyfailed, surface the existing error.Scope
src/cli/ui/state/state.ts(addmcpLoadingtoStatusBar),src/cli/ui/state/reducer.ts(event → state),src/cli/ui/App.tsx(already has the lifecycle sink — push to state),src/cli/ui/layout/StatusRow.tsx(render). Small i18n string add.src/mcp/runtime.ts(or wherever the per-server lifecycle lives — track areadydeferred per spec),src/mcp/registry.ts(await it beforecallTool). One integration test that firescallToolmid-handshake and asserts it resolves rather than rejects.Either gap is independently shippable — separate PRs welcome. Both are good-first-issue scope.