Skip to content

fix(webui): label each MCP server's connection state on the plugin row (D-3) - #27

Merged
stevenjj33 merged 1 commit into
webuifrom
fix/webui-mcp-plugin-status
Oct 5, 2026
Merged

stevenjj33 merged 1 commit into
webuifrom
fix/webui-mcp-plugin-status

Conversation

@stevenjj33

Copy link
Copy Markdown
Collaborator

Change

Roadmap D-3(转述口径,fork 的 issues 已禁用、roadmap 在团队侧,仓内无 D-3 字样可核): 「MCP 插件连不上时,界面上要看得见」.

Investigation first. The runtime already classifies every MCP server and puts it on the wire — LocalMcpPublicServerStatus (local-runtime-v2/src/service/mcp/contracts.ts) carries status: available | configured | disabled | error | unavailable plus the failure's own reason string on the two trouble states, produced by listPublicServerStatuses (runtimeErrors → error + reason; static prerequisites missing → unavailable + reason). The WebUI panel's MCP rows rendered none of it: the mcp area's row had only 编辑 / 删除 / 启用开关 — a server that could not connect was visually identical to a healthy one. (appStatus exists but is rendered only in the apps area.)

Fix — a status chip in the slot the apps area already uses, plus the reason as visible text:

  • describeWebuiMcpServerStatus (exported pure function in PluginManagement.tsx): maps the row's loose status onto a labelled view — 已连接 / 未连接 / 已停用 for the calm states (configured is deliberately NOT trouble: enabled-and-resting is a server that connects on use), 连接失败 in the danger tone and 不可用 in the warning tone for the trouble states, each carrying the runtime's own reason (error / errorMessage keys).
  • The reason renders inline as visible text — not a tooltip, because nobody hovers a row they believe is healthy — ellipsis-clamped with the full string on the element's title, so a long server error cannot push the 编辑/删除/开关 strip out of the row. Small CSS addition (.webui-plugin-mcp-status).
  • Unknown / missing status → 未知状态 with no invented reason: the label claims nothing, and a reason under it would claim something the reader cannot verify.

Browser verification (built client, real Chromium, walked the real path): rail 插件 → 管理 → MCP tab with a staged listing covering all five states —

server status rendered reason rendered
broken-http error 连接失败 MCP_CONNECTION_TIMEOUT: 握手超时(10s) — inline, visible
gone-binary unavailable 不可用 MCP_COMMAND_NOT_FOUND: ./missing-bin — inline, visible
ok-stdio available 已连接 —
idle configured 未连接 —
off disabled 已停用 —

Before the change the same listing rendered no status text anywhere in the rows.

Validation

  • pnpm test:webui — 83 files / 1653 tests passed, including new plugin-mcp-status.test.tsx (6 cases: per-state labels, reason passthrough for both trouble states incl. the errorMessage key, trouble tones ≠ neutral tone, unknown-claims-nothing, row-wiring source assertions).
  • npx playwright test — 88/88 passed, including new plugin-mcp-status.spec.mjs (2 cases, harness-imported test: failure states labelled with their server's own reason via the real rail→管理→MCP path; calm states labelled so trouble has honest neighbours; no invented reasons).
  • pnpm typecheck:webui-full, pnpm check:source (inventory regenerated), pnpm verify — passed, 20 gates on darwin.
  • Fixture change is additive: setPluginManagementResult(action, result) keyed per action; default stays {}, existing specs untouched.

NOT RUN / boundaries

  • The staged listing runs against the fixture transport; no real MCP server was crashed end-to-end (that needs a live pnpm dev:server session with a real failing server config). The status/reason fields consumed are the runtime's own contract, source-verified at listPublicServerStatuses.
  • Scope note: visibility lives in the plugin panel (the plugins home). A rail-level badge on 插件 for ambient discovery would need shell-side MCP polling — out of scope here, worth a follow-up if wanted.

Publication and contribution checks

  • I have permission to contribute these changes under the existing licenses applicable to the changed files/packages; imported material and its provenance are identified and existing notices are preserved.
  • No credentials, account data, real user content, internal source history or private review material is included.
  • Added/removed source files were reviewed before regenerating release/public-source.json; new tests are declared in test/vitest-suites.json where applicable.
  • Shared English/Chinese documentation and capability/verification records are updated where applicable. Mock/offline results are not described as live-service acceptance.

Maintainer handoff

Publication scope or license changes (if any): none.

Shared-source port: not needed.

Roadmap D-3 (as transcribed): MCP 插件连不上时,界面上要看得见. The
runtime already classifies every server (LocalMcpPublicServerStatus:
available / configured / disabled / error / unavailable) and attaches
the failure's own reason to the two trouble states — the panel's MCP
rows rendered none of it, so a server that could not connect was
visually identical to a healthy one, and the only difference left on
the row was its tool count not appearing anywhere either.

The row now carries a status chip in the slot the apps area already
uses for its runtime state: 已连接 / 未连接 / 已停用 for the calm
states (configured is deliberately NOT trouble — enabled and resting
is a server that connects on use), 连接失败 in the danger tone and
不可用 in the warning tone for the trouble states, each with the
runtime's own reason string as visible inline text (ellipsis-clamped
with the full text on the title, so a long server error cannot push
the 编辑/删除/开关 strip out of the row). The mapping lives in an
exported pure function, describeWebuiMcpServerStatus, reading the
loose row shape the panel already uses.

The browser fixture gains setPluginManagementResult(action, result)
so a listing with every connection state can be staged for the
panel's reload.

Tests: plugin-mcp-status.test.tsx (6 — each state's label, reason
passthrough for error/unavailable including the errorMessage key,
trouble states do not share the neutral tone, unknown status claims
nothing, plus row-wiring source assertions) and
plugin-mcp-status.spec.mjs (2 browser cases walking the real path —
rail 插件 → 管理 → MCP — reading placed, loaded rows: failure states
labelled with their server's own reason, calm states labelled so
trouble has honest neighbours, and no invented reasons).
@stevenjj33 stevenjj33 added the bug Something isn't working label Oct 5, 2026
@stevenjj33
stevenjj33 merged commit 1b83d2b into webui Oct 5, 2026
9 checks passed
@stevenjj33
stevenjj33 deleted the fix/webui-mcp-plugin-status branch October 5, 2026 13:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant