---
phase: 36-unify-uimimetype-and-extendeduimimetype-with-from-bridge
plan: 01
type: tdd
wave: 1
depends_on: []
files_modified:
  - src/types/mcp_apps.rs
autonomous: true
requirements:
  - MIME-BRIDGE-01

must_haves:
  truths:
    - "UIMimeType values convert infallibly to ExtendedUIMimeType via .into()"
    - "ExtendedUIMimeType shared variants convert back to UIMimeType via try_from()"
    - "ExtendedUIMimeType extended-only variants fail conversion to UIMimeType with descriptive error"
    - "Round-trip UIMimeType -> ExtendedUIMimeType -> UIMimeType preserves the original value"
  artifacts:
    - path: "src/types/mcp_apps.rs"
      provides: "From<UIMimeType> for ExtendedUIMimeType impl"
      contains: "impl From<crate::types::ui::UIMimeType> for ExtendedUIMimeType"
    - path: "src/types/mcp_apps.rs"
      provides: "TryFrom<ExtendedUIMimeType> for UIMimeType impl"
      contains: "impl TryFrom<ExtendedUIMimeType> for crate::types::ui::UIMimeType"
  key_links:
    - from: "src/types/mcp_apps.rs"
      to: "src/types/ui.rs"
      via: "From/TryFrom trait impls bridging ExtendedUIMimeType and UIMimeType"
      pattern: "impl From<crate::types::ui::UIMimeType>"
---

<objective>
Add bidirectional type conversion between UIMimeType (3 variants, always available) and ExtendedUIMimeType (7 variants, mcp-apps feature). Implement From<UIMimeType> for ExtendedUIMimeType (infallible) and TryFrom<ExtendedUIMimeType> for UIMimeType (fallible for extended-only variants).

Purpose: Enable seamless conversion between the two MIME type enums so Phase 37 (TypedSyncTool with_ui) can pass values across the feature-gate boundary without manual matching at each call site.
Output: Two trait impls and comprehensive tests in src/types/mcp_apps.rs
</objective>

<execution_context>
@./.claude/get-shit-done/workflows/execute-plan.md
@./.claude/get-shit-done/templates/summary.md
</execution_context>

<context>
@.planning/PROJECT.md
@.planning/ROADMAP.md
@.planning/STATE.md
@.planning/phases/36-unify-uimimetype-and-extendeduimimetype-with-from-bridge/36-RESEARCH.md
@src/types/ui.rs
@src/types/mcp_apps.rs
</context>

<tasks>

<task type="auto" tdd="true">
  <name>Task 1: Write failing tests for From and TryFrom bridge</name>
  <files>src/types/mcp_apps.rs</files>
  <behavior>
    - test_from_ui_mime_type: UIMimeType::HtmlMcp.into() == ExtendedUIMimeType::HtmlMcp, same for HtmlSkybridge and HtmlMcpApp
    - test_try_from_extended_shared: TryFrom succeeds for HtmlMcp, HtmlSkybridge, HtmlMcpApp returning matching UIMimeType variants
    - test_try_from_extended_fails: TryFrom returns Err for HtmlPlain, UriList, RemoteDom, RemoteDomReact with message containing "extended-only variant"
    - test_mime_type_round_trip: For each UIMimeType variant, convert to Extended then back via try_from, assert equality
  </behavior>
  <action>
Add 4 test functions to the existing `mod tests` block in src/types/mcp_apps.rs. Import `crate::types::ui::UIMimeType` and `std::convert::TryFrom` at the top of the test module.

Tests to add (all inside the existing `#[cfg(test)] mod tests`):

1. `test_from_ui_mime_type` -- For each of the 3 UIMimeType variants, call `.into()` and assert the resulting ExtendedUIMimeType matches the expected variant. Also verify `as_str()` matches between source and target.

2. `test_try_from_extended_shared` -- For ExtendedUIMimeType::HtmlMcp, HtmlSkybridge, HtmlMcpApp, call `UIMimeType::try_from(ext)` and assert Ok with matching variant. Verify `as_str()` matches.

3. `test_try_from_extended_fails` -- For HtmlPlain, UriList, RemoteDom, RemoteDomReact, call `UIMimeType::try_from(ext)` and assert `is_err()`. Check error string contains "extended-only variant".

4. `test_mime_type_round_trip` -- For each UIMimeType variant: convert to ExtendedUIMimeType via `.into()`, convert back via `UIMimeType::try_from()`, assert original == round-tripped.

These tests MUST fail (compile error) since From/TryFrom impls do not exist yet. Commit the failing state.
  </action>
  <verify>
    <automated>cd /Users/guy/Development/mcp/sdk/rust-mcp-sdk && cargo test --features mcp-apps -p pmcp types::mcp_apps::tests::test_from_ui_mime_type 2>&1 | grep -E "error|FAILED"</automated>
  </verify>
  <done>4 test functions exist in mcp_apps.rs tests module. They fail to compile because From/TryFrom impls are missing.</done>
</task>

<task type="auto" tdd="true">
  <name>Task 2: Implement From and TryFrom bridge impls</name>
  <files>src/types/mcp_apps.rs</files>
  <action>
Add two trait implementations in src/types/mcp_apps.rs, placed directly after the `ExtendedUIMimeType` impl block (after the `FromStr` impl, before the `// UI Content Types` section comment around line 736).

1. `impl From<crate::types::ui::UIMimeType> for ExtendedUIMimeType`:
   - Match all 3 UIMimeType variants explicitly (NO wildcard) to their ExtendedUIMimeType counterparts:
     - HtmlMcp -> Self::HtmlMcp
     - HtmlSkybridge -> Self::HtmlSkybridge
     - HtmlMcpApp -> Self::HtmlMcpApp
   - Use explicit `crate::types::ui::UIMimeType` path (not `use` import to avoid ambiguity)

2. `impl TryFrom<ExtendedUIMimeType> for crate::types::ui::UIMimeType`:
   - `type Error = String` (matches existing FromStr error type on both enums)
   - Match all 7 ExtendedUIMimeType variants explicitly (NO wildcard):
     - HtmlMcp, HtmlSkybridge, HtmlMcpApp -> Ok(Self::corresponding_variant)
     - HtmlPlain, UriList, RemoteDom, RemoteDomReact -> Err with format!("Cannot convert {} to UIMimeType (extended-only variant)", other)
   - Use `other` binding in Err arms to get Display output

After implementing, run the full test suite to confirm all 4 new tests pass AND all existing tests still pass. Also run clippy.
  </action>
  <verify>
    <automated>cd /Users/guy/Development/mcp/sdk/rust-mcp-sdk && cargo test --features mcp-apps -p pmcp types::mcp_apps::tests -- mime && cargo test --features mcp-apps -p pmcp types::mcp_apps::tests::test_from_ui_mime_type && cargo test --features mcp-apps -p pmcp types::mcp_apps::tests::test_try_from_extended && cargo test --features mcp-apps -p pmcp types::mcp_apps::tests::test_mime_type_round_trip && cargo clippy --features mcp-apps -p pmcp -- -D warnings 2>&1 | tail -5</automated>
  </verify>
  <done>All 4 new bridge tests pass. All existing mcp_apps tests pass. Zero clippy warnings. From<UIMimeType> for ExtendedUIMimeType and TryFrom<ExtendedUIMimeType> for UIMimeType are implemented with explicit match arms (no wildcards).</done>
</task>

</tasks>

<verification>
1. `cargo test --features mcp-apps -p pmcp types::mcp_apps::tests` -- all tests green
2. `cargo test --features mcp-apps -p pmcp` -- full crate tests green
3. `cargo clippy --features mcp-apps -p pmcp -- -D warnings` -- zero warnings
4. `cargo test -p pmcp` -- non-mcp-apps build still compiles (From/TryFrom are feature-gated)
</verification>

<success_criteria>
- UIMimeType::HtmlMcp.into() returns ExtendedUIMimeType::HtmlMcp (and same for other 2 shared variants)
- UIMimeType::try_from(ExtendedUIMimeType::HtmlMcp) returns Ok(UIMimeType::HtmlMcp)
- UIMimeType::try_from(ExtendedUIMimeType::HtmlPlain) returns Err with descriptive message
- Round-trip conversion preserves values for all 3 shared variants
- No wildcards in match arms (compiler catches future variant additions)
- Zero clippy warnings, all existing tests pass
</success_criteria>

<output>
After completion, create `.planning/phases/36-unify-uimimetype-and-extendeduimimetype-with-from-bridge/36-01-SUMMARY.md`
</output>
