Skip to content

v0.9.2: Split mcp.rs transports into focused modules #3310

Description

@Hmbown

Problem

crates/tui/src/mcp.rs bundled every MCP concern in one file. The transport half of the split has since landed: StdioTransport, SseTransport, StreamableHttpTransport, header helpers, OAuth, and the test module all live under crates/tui/src/mcp/ now. The root file is still 3,189 lines because the HTTP transport, connection lifecycle, pool, config load/save, and discovery-snapshot layers never moved. The remaining boundaries are just as natural as the ones already cut; finishing the split keeps each concern reviewable and stops unrelated MCP work from colliding in one file.

Current evidence

Measured at v0.9.1 (2026-07-18):

  • Already extracted: crates/tui/src/mcp/stdio.rs (313 lines), mcp/sse.rs (346), mcp/streamable_http.rs (209), mcp/headers.rs (65), mcp/oauth.rs (1,179), mcp/tests.rs (3,887 lines, 102 tests). Transports implement the shared McpTransport trait and import root helpers via use super::{...}.
  • Root crates/tui/src/mcp.rs (3,189 lines) still holds:
    • Config-path validation and env expansion: validate_mcp_config_path (42), expand_env_placeholders (63), mcp_stdio_child_env (110).
    • Command availability probing: McpCommandAvailability (118), static_mcp_command_availability (238).
    • Secret redaction (security-sensitive): mask_url_secrets (286), redact_proxy_userinfo (305), redact_body_preview (334), bounded_body_excerpt (360), invalid_json_preview (375).
    • Config types: McpConfig (395), McpTimeouts (405), McpServerConfig (436), McpServerOAuthConfig (522).
    • Discovery item types: McpTool (566), McpResource (603), McpResourceTemplate (614), McpPrompt (626).
    • ConnectionState (648), McpServerCapabilities (655), response_result (672), run_optional_discovery (682).
    • McpTransport trait (715) — the common abstraction already exists.
    • The last unextracted transport: HttpTransport + McpHttpAuth (726–939, impl McpTransport at 895).
    • SSE wire-format parsing shared by three transports: parse_sse_message_data (963), find_sse_event_separator[_bytes] (994/1008), sse_field_value (1029); stale-session detection (940–962); validate_mcp_transport (1042).
    • Connection lifecycle: McpConnection (1067–1761) and McpPool (1763–2540).
    • Snapshot types (2541–2578) and config load/save/init: load_config (2579), workspace_mcp_config_path (2629), load_config_with_workspace (2635), plugin merge (2648–2712), workspace path safety (checked_workspace_mcp_config_path 2717, checked_workspace_path 2723, normalize_path_components 2783), save_config (2840), init_config (2908), add_server_config (2929), remove_server_config (2970), set_server_enabled (2978).
    • Discovery snapshot: manager_snapshot_from_config[_with_workspace] (2990/3004), discover_manager_snapshot[_with_workspace] (3020/3045), snapshot_from_config (3071).
    • mod tests; (3189).
  • Consumers span 14 files including crates/tui/src/main.rs, crates/tui/src/tools/registry.rs, crates/tui/src/tools/runtime_mcp.rs, crates/tui/src/core/engine.rs, crates/tui/src/runtime_api.rs, and the TUI setup/MCP routing surfaces — so root re-exports must keep crate::mcp::X paths stable.

Scope

One transport/concern per PR, smallest first:

  1. mcp/http.rs — move HttpTransport, HttpTransportMode, McpHttpAuth, and mcp_headers_have_authorization (726–939). After this every transport lives in its own module.
  2. mcp/wire.rs (or fold into an existing helper module) — the shared SSE wire parsing + stale-session/connection-closed detection (940–1066), imported by sse.rs, streamable_http.rs, and http.rs.
  3. mcp/connection.rsConnectionState, McpServerCapabilities, response_result, run_optional_discovery, response_id_matches, McpConnection + Drop (1067–1761).
  4. mcp/pool.rsMcpPool (1763–2540).
  5. mcp/config.rs — config types (395–565), env expansion + config-path validation (42–116), load/save/init/add/remove/enable (2579–2989) including the workspace path-safety helpers, which must move verbatim.
  6. mcp/snapshot.rs — snapshot types (2541–2578) plus manager_snapshot_* / discover_manager_snapshot_* / snapshot_from_config (2990–3188).
  7. Keep in the root: McpTransport trait, the redaction helpers (or give them a tiny mcp/redact.rs), command-availability probing, and re-exports preserving today's public paths.

Key files

  • crates/tui/src/mcp.rs
  • crates/tui/src/mcp/tests.rs
  • crates/tui/src/mcp/stdio.rs
  • crates/tui/src/mcp/sse.rs
  • crates/tui/src/mcp/streamable_http.rs
  • crates/tui/src/mcp/headers.rs

Acceptance criteria

  • Each transport implementation (stdio, SSE, HTTP, streamable HTTP) lives in its own module; McpTransport and shared types stay in a small common surface.
  • Connection lifecycle (McpConnection, McpPool) is separated from individual transports and from config I/O.
  • Config loading/saving and the discovery snapshot are in their own modules; workspace path-safety (checked_workspace_*) and secret-redaction helpers move whole with behavior unchanged.
  • All 102 tests in mcp/tests.rs pass unmodified; consumers keep compiling with crate::mcp:: paths (root re-exports, no broad pub sweep — extracted transports today are pub(super), keep that bar).
  • No duplicated helper logic between root and new modules.

Verification

cargo test -p codewhale-tui --bin codewhale-tui --locked mcp
cargo fmt

Include one config load/save/discovery smoke in the touched-test run (already covered inside mcp/tests.rs).

Out of scope

  • Any behavior change to transports, auth, retry/stale-session handling, or discovery.
  • crates/tui/src/mcp_server.rs (the server side) and tools/runtime_mcp.rs beyond import updates.
  • OAuth flows (mcp/oauth.rs is already separate).

Related

Triage note: body restructured for agent execution on 2026-07-18; prior comment refinements folded in. Original wording preserved in edit history.

Metadata

Metadata

Assignees

No one assigned

    Labels

    agent-readySelf-contained for a fresh-clone cloud agent; implement in a tested PR with no live credentialscleanupCode cleanup, refactor, or maintenance workenhancementNew feature or requestreliabilityReliability, flaky behavior, retries, fallbacks, and robustnessrustPull requests that update rust codetoolsTool execution, tool schemas, tool UX, and built-in tool behaviortuiTerminal UI behavior, rendering, or interactionv0.9.2Targeting v0.9.2

    Projects

    Status
    Backlog

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions