Skip to content

feat(settings): read-only MCP Servers tab in the settings modal#28

Merged
saucam merged 3 commits into
mainfrom
feat/tui-mcp-settings
Jul 19, 2026
Merged

feat(settings): read-only MCP Servers tab in the settings modal#28
saucam merged 3 commits into
mainfrom
feat/tui-mcp-settings

Conversation

@saucam

@saucam saucam commented Jul 19, 2026

Copy link
Copy Markdown
Collaborator

What

Brings the cross-backend MCP registry surface to the TUI, matching the web's "🔌 MCP Servers" settings tab (codeoid #203). Until now the daemon emitted mcpServers on the settings snapshot but only the web rendered it — the TUI was blind to it (unbroken, just no view). Now every frontend shows it.

Changes

  • codeoid-protocolMcpServerStatus struct + a mcp_servers field on SettingsSnapshot. #[serde(default)] keeps it forward-compatible: an older daemon that doesn't send the field deserializes fine (empty).
  • statehas_mcp_tab() / on_mcp_tab() and tab_count() appends a synthetic MCP tab after the manifest tabs only when the daemon reports servers. tab_fields() is already empty there, so field navigation / edit / save no-op on the read-only tab — zero changes needed in the key handlers.
  • ui — a header pill + mcp_server_rows: per server, a colour-coded health chip (connected/error/idle/disabled), transport · trust · N tools, error text, tool list, backends, and a built-in badge for codeoid_memory.

Tests

A state test asserts the synthetic tab appears only when servers exist, sits after the manifest tabs, exposes no fields, and disappears when the list empties. cargo fmt --check clean; 284 tests pass; clippy is advisory (no new error-level lints).

Note

This depends on the daemon sending mcpServers in the settings snapshot (codeoid #203). The Rust struct is a hand-maintained mirror of the TS McpServerStatus — the usual codeoid-protocol convention.

🤖 Generated with Claude Code

Mirror the web's "🔌 MCP Servers" settings surface in the TUI, so the
cross-backend MCP registry is visible from every frontend (not just web).

- protocol: `McpServerStatus` + a `mcp_servers` field on `SettingsSnapshot`
  (`#[serde(default)]` → forward-compatible; older daemons deserialize fine).
- state: `has_mcp_tab()` / `on_mcp_tab()` + `tab_count()` appends the synthetic
  MCP tab after the manifest tabs when the daemon reports servers. `tab_fields()`
  is already empty there, so field nav/edit/save no-op on the read-only tab.
- ui: a header pill + a body renderer (`mcp_server_rows`) showing each server's
  health (connected/error/idle/disabled, colour-coded), transport · trust ·
  tool count, error text, tool list, and backends; `built-in` badge for memory.

Test: the synthetic tab appears only when servers exist, sits after the manifest
tabs, exposes no fields, and disappears when the list empties. fmt clean; 284
tests pass; clippy advisory (no new error-level lints).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Comment thread crates/codeoid-tui/src/state/mod.rs
@github-actions

Copy link
Copy Markdown

🤖 Gemini code review

This PR introduces a read-only 'MCP Servers' tab to the TUI settings modal, bringing feature parity with the web interface. It appends a synthetic tab when the daemon reports registry MCP servers and displays their health status, tools, and error messages.

Findings: 🔴 0 · 🟠 0 · 🟡 0 · 🟢 1


Tokens spent · ⬆️ Input: 3,919 · ⬇️ Output: 318 · Σ Total: 7,462
Total may be higher due to thinking token counts.

@codecov

codecov Bot commented Jul 19, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 93.17073% with 14 lines in your changes missing coverage. Please review.
✅ Project coverage is 70.30%. Comparing base (efe6cc1) to head (f7dd05d).
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
crates/codeoid-tui/src/ui/modal.rs 91.17% 12 Missing ⚠️
crates/codeoid-tui/src/app.rs 0.00% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main      #28      +/-   ##
==========================================
+ Coverage   68.78%   70.30%   +1.51%     
==========================================
  Files          31       31              
  Lines        9659     9862     +203     
==========================================
+ Hits         6644     6933     +289     
+ Misses       3015     2929      -86     
Flag Coverage Δ
tui 70.30% <93.17%> (+1.51%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
crates/codeoid-tui/src/state/mod.rs 82.51% <100.00%> (+5.02%) ⬆️
crates/codeoid-tui/src/app.rs 51.42% <0.00%> (-0.05%) ⬇️
crates/codeoid-tui/src/ui/modal.rs 39.13% <91.17%> (+17.63%) ⬆️

saucam and others added 2 commits July 20, 2026 00:09
…r path)

Renders the settings modal on the synthetic MCP tab via TestBackend and asserts
the pill, server names, built-in badge, health chip, and tool list appear —
covering mcp_server_rows + the header pill branch (lifts patch coverage).
If parked on the synthetic MCP tab and a fresh snapshot drops mcp_servers, the
tab index was left out of range (safe .get() → blank body until next ←/→).
Add SettingsModal::clamp_tab() and call it whenever the snapshot updates
(settings.get/set results). No panic before; this removes the blank-body papercut.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@saucam
saucam merged commit a931187 into main Jul 19, 2026
3 checks passed
@saucam saucam mentioned this pull request Jul 19, 2026
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.

1 participant