|
| 1 | +# Official Registry Install UI Implementation Plan |
| 2 | + |
| 3 | +## Objectives |
| 4 | +- Replace the dual-button install flow in `web/src/components/RegistryServerCard.tsx` with a single, program-aware install experience. |
| 5 | +- Allow users to target **VS Code** or **Claude Code** when installing MCP servers sourced from the official registry. |
| 6 | +- Preserve and extend existing registry normalization logic while eliminating reliance on `any` for the new pathways. |
| 7 | +- Reuse the existing `installFromConfig` pipeline for VS Code installs and introduce an analogous, well-typed request for Claude CLI installs. |
| 8 | + |
| 9 | +## Current State Summary |
| 10 | +- Registry search uses `SearchRegistryServers.tsx` to render `RegistryServerCard` items. Each card currently exposes independent **Install Local** (stdio) and **Install Remote** buttons tied to `installFromConfigType`. |
| 11 | +- The install payload builders already normalize runtime arguments, env vars, and HTTP headers but defer prompting via `inputs` placeholders. |
| 12 | +- Extension-side handling in `src/panels/ExtensionPanel.ts` funnels installs through `openMcpInstallUri`, which constructs a `vscode:mcp/install` URI. No Claude CLI integration exists today. |
| 13 | + |
| 14 | +## UI & Front-End Changes |
| 15 | +1. **Introduce Program Selection** |
| 16 | + - Add a `toggle` or `segmented` control (reusing `ToggleGroup` from `SearchMCPServers.tsx`) at the top of `RegistryServerCard` to switch between `VSCode` and `ClaudeCode`. |
| 17 | + - Store the choice in a new `programTarget` state typed as `'vscode' | 'claude'`. |
| 18 | + |
| 19 | +2. **Unify Install Mode Selection** |
| 20 | + - Replace the dual buttons with a secondary control that selects the install mode when both stdio packages and remote transports are available. |
| 21 | + - Define `installMode` state typed as `'package' | 'remote'`, defaulting to the first available option. Hide the selector when only one mode exists. |
| 22 | + - Continue to surface the existing `Select` components for choosing the specific package or remote endpoint within each mode. |
| 23 | + |
| 24 | +3. **Single Install Call-To-Action** |
| 25 | + - Render one primary `Button` whose label reflects both `programTarget` and `installMode` (e.g., `Install Package in VS Code`, `Add Remote to Claude Code`). |
| 26 | + - Reuse the existing `isInstallingLocal/isInstallingRemote` state by replacing them with a single `isInstalling` boolean plus optional status text (e.g., `Installing in Claude Code…`). |
| 27 | + - Ensure disabled states respect missing selections, unsupported transports, or unresolved builder errors. |
| 28 | + |
| 29 | +4. **User Feedback Enhancements** |
| 30 | + - Surface inline helper text when the Claude CLI is not detected (fed from new extension response metadata). |
| 31 | + - Preserve repository/website links and descriptive metadata already present on the card. |
| 32 | + |
| 33 | +## Shared Data & Type Improvements |
| 34 | +1. **Create Shared Install Payload Types** |
| 35 | + - In `src/shared/types/rpcTypes.ts`, extract new interfaces: |
| 36 | + ```ts |
| 37 | + interface InstallInput { type: 'promptString'; id: string; description?: string; password?: boolean; } |
| 38 | + interface InstallCommandPayload { |
| 39 | + name: string; |
| 40 | + command?: string; |
| 41 | + args?: string[]; |
| 42 | + env?: Record<string, string>; |
| 43 | + url?: string; |
| 44 | + headers?: Array<{ name: string; value: string }>; |
| 45 | + inputs?: InstallInput[]; |
| 46 | + } |
| 47 | + ``` |
| 48 | + - Update `installFromConfigType` to reference `InstallCommandPayload` instead of inline `any`-adjacent shapes. |
| 49 | + |
| 50 | +2. **Add Claude-Specific Request Type** |
| 51 | + - Define `installClaudeFromConfigType: RequestType<InstallCommandPayload & { transport: 'stdio' | 'http' | 'sse'; mode: 'package' | 'remote'; }, { success: boolean; cliAvailable: boolean; errorMessage?: string }>` within the same module. |
| 52 | + - Export the new type to webview components. |
| 53 | + |
| 54 | +3. **Refactor Front-End Builders** |
| 55 | + - Extract the argument/env/header normalization helpers from `RegistryServerCard.tsx` into a local utility (e.g., `web/src/utils/registryInstall.ts`) returning strongly typed results: |
| 56 | + ```ts |
| 57 | + interface BuildResult { |
| 58 | + payload: InstallCommandPayload; |
| 59 | + missingInputs: InstallInput[]; |
| 60 | + unavailableReason?: string; |
| 61 | + } |
| 62 | + ``` |
| 63 | + - Ensure functions use typed registry models (`RegistryPackage`, `RegistryTransport`) without `any`. |
| 64 | + - Allow the builder to report when a transport is unsupported (e.g., OCI without a runtime hint) so the UI can disable the install mode gracefully. |
| 65 | + |
| 66 | +## Extension (Back-End) Adjustments |
| 67 | +1. **Handle New Claude Install Request** |
| 68 | + - In `src/panels/ExtensionPanel.ts`, register `messenger.onRequest(installClaudeFromConfigType, …)`. |
| 69 | + - For each incoming request: |
| 70 | + - Iterate over `payload.inputs ?? []` and gather values using `vscode.window.showInputBox({ prompt: input.description, password: input.password ?? false, ignoreFocusOut: true })`. |
| 71 | + - Substitute the collected responses into `payload.args`, `payload.env`, and `payload.headers` before invoking the CLI. |
| 72 | + - Leverage VS Code’s terminal/task APIs instead of spawning child processes directly: |
| 73 | + - Construct a `ShellExecution` via `new vscode.ShellExecution(claudeBinary, ['mcp', 'add-json', payload.name, configJson])`, where `claudeBinary` is resolved per platform and `configJson` is the filtered JSON string. |
| 74 | + - Create a temporary `Task` (e.g., `"Claude MCP Install"`) scoped to the workspace and execute it using `vscode.tasks.executeTask`. |
| 75 | + - Subscribe to `vscode.tasks.onDidEndTaskProcess` to capture the exit code and translate it into `{ success: boolean; cliAvailable: boolean; errorMessage?: string }`. |
| 76 | + - On `code === undefined` with an associated `ShellExecution` error indicating a missing binary, report `{ success: false, cliAvailable: false }`. |
| 77 | + - Optionally surface a toast (`vscode.window.showInformationMessage`) when the task finishes successfully. |
| 78 | + - Ensure the temporary task/terminal is disposed after completion to avoid clutter (use `TaskPresentationOptions` with `reveal: Never` and `isTransient: true`). |
| 79 | + |
| 80 | +2. **Reuse Existing Telemetry Utilities** |
| 81 | + - Call `logWebviewInstallAttempt(payload.name)` with an additional context flag (e.g., program target) if telemetry schema allows. |
| 82 | + - Log failures via `logError` with a Claude-specific tag. |
| 83 | + |
| 84 | +3. **Shared Utility Extraction** |
| 85 | + - Move `openMcpInstallUri` invocation behind a helper that accepts `InstallCommandPayload`. Update current VS Code handler to use the same helper for clarity and future reuse. |
| 86 | + |
| 87 | +## Webview ⇄ Extension Interaction |
| 88 | +- Update `RegistryServerCard.tsx` to await the Claude install response, check `cliAvailable`, and set inline error state (e.g., `setInstallError({ message, missingCli: !cliAvailable })`). |
| 89 | +- When CLI is missing, present actionable UI: offer a link to installation docs (using `mcp.md` anchor) and provide a `Copy Command` button that copies the generated CLI command to the clipboard via a new `copyClaudeCommand` helper (pure web side). |
| 90 | +- Maintain existing VS Code behavior, including progress state updates and error handling. |
| 91 | + |
| 92 | +## Documentation & Telemetry Updates |
| 93 | +- Append a changelog entry to `WHATS_NEW.md` describing the unified install flow and Claude support. |
| 94 | +- Reference relevant `mcp.md` sections if we need to guide users toward Claude CLI installation. |
| 95 | +- Confirm telemetry event naming with `TelemetryEvents` to avoid schema drift; add new enums if necessary without using `any`. |
| 96 | + |
| 97 | +## Testing & Validation |
| 98 | +1. **Automated** |
| 99 | + - Run `pnpm lint` and any available type checks (`pnpm tsc --noEmit`) to verify type safety after removing `any`. |
| 100 | +2. **Manual (VS Code)** |
| 101 | + - Search a registry server with only stdio packages; install to VS Code and confirm `vscode:mcp/install` prompt appears. |
| 102 | + - Search a server with only remote endpoints; verify install disables stdio mode and succeeds via VS Code. |
| 103 | +3. **Manual (Claude)** |
| 104 | + - With Claude CLI available, install both package and remote variants; confirm CLI reports success and new server appears in `claude mcp list`. |
| 105 | + - Without the CLI, ensure the UI surfaces guidance and copying the command works. |
| 106 | +4. **Edge Cases** |
| 107 | + - Validate flows when required inputs/environment variables are missing; prompts should appear before CLI execution. |
| 108 | + - Confirm telemetry logs without throwing when installs fail or are canceled. |
| 109 | + |
| 110 | +## Follow-Up Considerations |
| 111 | +- Evaluate consolidating similar install logic for GitHub-sourced servers to reuse the new helpers. |
| 112 | +- Investigate caching CLI availability detection to avoid repeating spawn checks on every card interaction. |
| 113 | +- Consider localizing new UI strings via existing localization patterns if/when introduced. |
0 commit comments