Skip to content

Commit ce1d384

Browse files
committed
fix(ui): split one-click vs copy-paste install in Clients onboarding
The previous empty-state flow lumped "Add to VS Code" (auto-install via deep link) and "Copy config" (clipboard-only — user has to paste) into the same numbered list, making users think clicking any card auto-installed. The copy-paste tiles only put text on the clipboard; nothing happens in the target IDE until the user pastes it into a config file and restarts. Split into two labeled tracks on the Clients empty state: **Track A — One-click** (VS Code, Cursor): 1. Click → Add to X — IDE opens and registers mcpmux 2. New chat / reload MCP 3. Approve here **Track B — Manual** (Windsurf, Claude Code, JetBrains, Android Studio): 1. Click → Copy config / Copy command (clipboard) 2. Paste into the IDE's MCP config file (or run the command) 3. Restart / reload MCP in the IDE 4. Approve here Also tightened the ConnectIDEs popover so each card's blurb tells the user exactly what pressing the button will do + what they must do next: * deep_link → "Opens the IDE and registers mcpmux automatically. Start a new chat / reload MCP, then approve on the Clients page." * copy_command → "Copies a terminal command… Run it, restart the IDE, approve on the Clients page." * copy_config → "Copies a JSON snippet… Paste into the IDE's MCP config file, restart the IDE, approve on the Clients page." Card header description now says up-front that VS Code + Cursor are one-click and everything else copies a config. The "Copied!" tick now reads "Copied — paste & restart" so users don't think the button finished the job. Signed-off-by: Mohammod Al Amin Ashik <maa.ashik00@gmail.com>
1 parent b4ba091 commit ce1d384

2 files changed

Lines changed: 112 additions & 56 deletions

File tree

apps/desktop/src/components/ConnectIDEs.tsx

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -127,9 +127,9 @@ export function ConnectIDEs({ gatewayUrl, gatewayRunning }: ConnectIDEsProps) {
127127
<div>
128128
<CardTitle>Connect Your IDEs</CardTitle>
129129
<CardDescription>
130-
Add mcpmux to your AI client, then <span className="font-medium">restart / reconnect
131-
the MCP server in that client</span> — an approval prompt appears in this app when it
132-
hits the gateway.
130+
<span className="font-medium">VS Code &amp; Cursor</span> are one-click; the rest copy
131+
a config you paste into their MCP settings. Either path ends with an approval
132+
prompt in this app.
133133
</CardDescription>
134134
</div>
135135
<div className="flex items-center gap-1.5 text-xs text-[rgb(var(--muted))]">
@@ -176,14 +176,23 @@ export function ConnectIDEs({ gatewayUrl, gatewayRunning }: ConnectIDEsProps) {
176176
{/* Popover */}
177177
{isActive && (
178178
<div
179-
className="absolute top-full left-0 mt-2 z-10 w-44 rounded-lg border border-[rgb(var(--border))] bg-white dark:bg-zinc-900 shadow-lg p-2.5"
179+
className="absolute top-full left-0 mt-2 z-10 w-60 rounded-lg border border-[rgb(var(--border))] bg-white dark:bg-zinc-900 shadow-lg p-3"
180180
data-testid="client-popover"
181181
>
182182
{/* Arrow */}
183183
<div className="absolute -top-1.5 left-4 h-3 w-3 rotate-45 border-l border-t border-[rgb(var(--border))] bg-white dark:bg-zinc-900" />
184184

185-
<p className="text-xs font-medium mb-2 text-center relative">
186-
{entry.name}
185+
<p className="text-xs font-semibold mb-1 relative">{entry.name}</p>
186+
187+
{/* Per-action "what happens + what's next" blurb. Users
188+
kept asking "did it install? should I restart?" —
189+
state both up front. */}
190+
<p className="text-[11px] leading-snug text-[rgb(var(--muted))] mb-2.5">
191+
{entry.action === 'deep_link'
192+
? 'Opens the IDE and registers mcpmux automatically. Start a new chat or reload MCP servers in the IDE, then approve on the Clients page.'
193+
: entry.action === 'copy_command'
194+
? 'Copies a terminal command to your clipboard. Run it in your shell, then restart the IDE and approve on the Clients page.'
195+
: 'Copies a JSON snippet to your clipboard. Paste it into the IDE’s MCP config file, restart the IDE, then approve on the Clients page.'}
187196
</p>
188197

189198
{entry.action === 'deep_link' ? (
@@ -199,7 +208,7 @@ export function ConnectIDEs({ gatewayUrl, gatewayRunning }: ConnectIDEsProps) {
199208
) : isCopied ? (
200209
<div className="flex items-center justify-center gap-1 text-xs text-green-600 h-7 relative">
201210
<Check className="h-3 w-3" />
202-
Copied!
211+
Copied — paste &amp; restart
203212
</div>
204213
) : (
205214
<Button

apps/desktop/src/features/clients/ClientsPage.tsx

Lines changed: 96 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -649,60 +649,107 @@ export default function ClientsPage() {
649649
<div>
650650
<h2 className="text-xl font-semibold">Connect your first IDE</h2>
651651
<p className="text-sm text-[rgb(var(--muted))] mt-1">
652-
Nothing has connected to mcpmux yet. It only takes three steps:
652+
Nothing has connected to mcpmux yet. Pick the path that matches your IDE
653+
below — the approval prompt shows up on this page either way.
653654
</p>
654655
</div>
655656
</div>
656657

657-
{/* Three-step flow. Each step is explicit so users don't
658-
get lost between "I added the config" and "why doesn't
659-
my client show up here?". */}
660-
<ol className="mt-6 space-y-3 text-sm">
661-
<li className="flex gap-3 items-start">
662-
<span className="flex-shrink-0 flex h-6 w-6 items-center justify-center rounded-full bg-primary-100 dark:bg-primary-900/40 text-primary-700 dark:text-primary-300 font-semibold text-xs">
663-
1
664-
</span>
665-
<div className="flex-1">
666-
<p className="font-medium">Add mcpmux to your IDE</p>
667-
<p className="text-[rgb(var(--muted))] text-xs mt-0.5">
668-
Pick one from the cards below — we&apos;ll copy the config or deep-link
669-
straight into the IDE.
670-
</p>
671-
</div>
672-
</li>
673-
<li className="flex gap-3 items-start">
674-
<RotateCcw className="h-5 w-5 mt-0.5 text-[rgb(var(--muted))] flex-shrink-0" />
675-
<span className="flex-shrink-0 flex h-6 w-6 items-center justify-center rounded-full bg-primary-100 dark:bg-primary-900/40 text-primary-700 dark:text-primary-300 font-semibold text-xs">
676-
2
677-
</span>
678-
<div className="flex-1">
679-
<p className="font-medium">Start or restart the MCP server in that IDE</p>
680-
<p className="text-[rgb(var(--muted))] text-xs mt-0.5">
681-
Some clients connect automatically on restart; others (Cursor, Claude
682-
Code) need you to toggle &quot;mcpmux&quot; on once.
683-
</p>
658+
{/* Two distinct install paths. Mixing them into a single
659+
numbered list made users think "copy config" auto-installs
660+
somewhere — it doesn't; it's clipboard content they have
661+
to paste themselves. Keep them separated. */}
662+
<div className="mt-6 grid grid-cols-1 md:grid-cols-2 gap-4">
663+
{/* Track A — one-click install (VS Code, Cursor) */}
664+
<div className="rounded-xl border border-primary-300/60 dark:border-primary-700/40 bg-gradient-to-br from-primary-50/50 to-transparent dark:from-primary-900/15 p-4">
665+
<div className="flex items-center gap-2 mb-3">
666+
<div className="flex h-7 w-7 items-center justify-center rounded-lg bg-primary-500 text-white text-xs font-bold">
667+
A
668+
</div>
669+
<h3 className="font-semibold text-sm">
670+
VS Code&nbsp;·&nbsp;Cursor
671+
<span className="ml-2 text-[10px] uppercase tracking-wide text-primary-700 dark:text-primary-300 bg-primary-500/10 rounded px-1.5 py-0.5">
672+
One-click
673+
</span>
674+
</h3>
684675
</div>
685-
</li>
686-
<li className="flex gap-3 items-start">
687-
<CheckCircle2 className="h-5 w-5 mt-0.5 text-[rgb(var(--muted))] flex-shrink-0" />
688-
<span className="flex-shrink-0 flex h-6 w-6 items-center justify-center rounded-full bg-emerald-100 dark:bg-emerald-900/40 text-emerald-700 dark:text-emerald-300 font-semibold text-xs">
689-
3
690-
</span>
691-
<div className="flex-1">
692-
<p className="font-medium">
693-
Approve the connection here
694-
<span className="ml-2 inline-flex items-center px-1.5 py-0.5 rounded-md bg-emerald-500/15 text-emerald-700 dark:text-emerald-300 text-[10px] font-semibold uppercase tracking-wide">
695-
on this page
676+
<ol className="space-y-2 text-xs">
677+
<li className="flex gap-2">
678+
<span className="font-semibold text-[rgb(var(--muted))] w-4 shrink-0">1.</span>
679+
<span>
680+
Click the IDE icon below → click <span className="font-medium">Add to VS Code</span> /
681+
<span className="font-medium"> Add to Cursor</span>. The IDE opens and registers mcpmux.
696682
</span>
697-
</p>
698-
<p className="text-[rgb(var(--muted))] text-xs mt-0.5">
699-
As soon as the IDE hits the gateway, mcpmux will pop an approval
700-
dialog. Pick a Space + FeatureSet pin and the client shows up right
701-
here. Nothing gets routed until you approve.
702-
</p>
683+
</li>
684+
<li className="flex gap-2">
685+
<span className="font-semibold text-[rgb(var(--muted))] w-4 shrink-0">2.</span>
686+
<span>
687+
Start a new chat / reload the MCP server in that IDE so it actually
688+
connects.
689+
</span>
690+
</li>
691+
<li className="flex gap-2">
692+
<span className="font-semibold text-emerald-600 dark:text-emerald-400 w-4 shrink-0">3.</span>
693+
<span>
694+
<span className="font-medium text-emerald-700 dark:text-emerald-300">
695+
Approve here.
696+
</span>{' '}
697+
mcpmux will pop a dialog on this app — nothing is routed to the IDE
698+
until you accept.
699+
</span>
700+
</li>
701+
</ol>
702+
</div>
703+
704+
{/* Track B — manual copy-paste (everyone else) */}
705+
<div className="rounded-xl border border-[rgb(var(--border))] bg-[rgb(var(--surface))] p-4">
706+
<div className="flex items-center gap-2 mb-3">
707+
<div className="flex h-7 w-7 items-center justify-center rounded-lg bg-[rgb(var(--muted))] text-white text-xs font-bold">
708+
B
709+
</div>
710+
<h3 className="font-semibold text-sm">
711+
Windsurf&nbsp;·&nbsp;Claude Code&nbsp;·&nbsp;JetBrains&nbsp;·&nbsp;Android Studio
712+
<span className="ml-2 text-[10px] uppercase tracking-wide text-[rgb(var(--muted))] bg-[rgb(var(--surface-elevated))] rounded px-1.5 py-0.5 border border-[rgb(var(--border))]">
713+
Manual
714+
</span>
715+
</h3>
703716
</div>
704-
</li>
705-
</ol>
717+
<ol className="space-y-2 text-xs">
718+
<li className="flex gap-2">
719+
<span className="font-semibold text-[rgb(var(--muted))] w-4 shrink-0">1.</span>
720+
<span>
721+
Click the IDE icon below → <span className="font-medium">Copy config</span> or
722+
<span className="font-medium"> Copy command</span> (your clipboard now has the
723+
snippet).
724+
</span>
725+
</li>
726+
<li className="flex gap-2">
727+
<span className="font-semibold text-[rgb(var(--muted))] w-4 shrink-0">2.</span>
728+
<span>
729+
Paste it into that IDE&apos;s MCP config file (or run the copied
730+
command for Claude Code).
731+
</span>
732+
</li>
733+
<li className="flex gap-2">
734+
<span className="font-semibold text-[rgb(var(--muted))] w-4 shrink-0">3.</span>
735+
<span>
736+
Restart the IDE or reload its MCP servers — mcpmux is not picked up
737+
until you do.
738+
</span>
739+
</li>
740+
<li className="flex gap-2">
741+
<span className="font-semibold text-emerald-600 dark:text-emerald-400 w-4 shrink-0">4.</span>
742+
<span>
743+
<span className="font-medium text-emerald-700 dark:text-emerald-300">
744+
Approve here.
745+
</span>{' '}
746+
mcpmux will pop a dialog on this app as soon as the IDE reaches the
747+
gateway.
748+
</span>
749+
</li>
750+
</ol>
751+
</div>
752+
</div>
706753

707754
{!gatewayStatus.running && (
708755
<div className="mt-5 flex items-start gap-2 p-3 rounded-lg border border-amber-300 dark:border-amber-700/60 bg-amber-50 dark:bg-amber-900/20 text-xs">
@@ -712,8 +759,8 @@ export default function ClientsPage() {
712759
Gateway is stopped
713760
</p>
714761
<p className="text-amber-700 dark:text-amber-300 mt-0.5">
715-
Start it from the Dashboard first, otherwise your IDE will sit at
716-
&quot;initialize&quot; forever.
762+
Start it from the Dashboard firstotherwise the IDE will hang at{' '}
763+
<code>initialize</code>.
717764
</p>
718765
</div>
719766
</div>

0 commit comments

Comments
 (0)