Skip to content

Commit b8485fa

Browse files
Dumbrisclaude
andcommitted
fix(web): make the first connect click explicitly commitment-free
The preview only appeared AFTER clicking "Connect" — the exact button hesitant users avoid, fearing the click immediately modifies their config. Rename the row action to "Review & connect" and say up front in the modal subtitle and wizard intro that nothing is written until the confirm step, so the safety of the first click is visible before it happens (Spec 078 US1 trust copy). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 parent d6cfcf0 commit b8485fa

3 files changed

Lines changed: 8 additions & 8 deletions

File tree

frontend/src/components/ConnectModal.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<div class="modal-box max-w-lg">
44
<h3 class="font-bold text-lg mb-2">Connect MCPProxy to AI Agents</h3>
55
<p class="text-sm opacity-70 mb-4">
6-
Register MCPProxy as an MCP server in your AI tools. This modifies the tool's config file (backup created automatically).
6+
Register MCPProxy as an MCP server in your AI tools. Clicking a client shows the exact change first — nothing is written until you confirm (backup created automatically).
77
</p>
88

99
<!-- Loading state -->
@@ -75,7 +75,7 @@
7575
:disabled="loading.clients[client.id] || previewLoading[client.id]"
7676
>
7777
<span v-if="loading.clients[client.id] || previewLoading[client.id]" class="loading loading-spinner loading-xs"></span>
78-
<span v-else>Connect</span>
78+
<span v-else>Review & connect</span>
7979
</button>
8080
<!-- Spec 075 US1: explicit, no-eager-read access check. The stat-only
8181
listing leaves installed clients 'unknown'; this is the only

frontend/src/components/OnboardingWizard.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@
4949
<!-- ============================ -->
5050
<section v-if="activeTab === 'clients'" data-test="panel-clients">
5151
<p class="text-sm opacity-70 mb-4">
52-
Pick at least one AI tool. MCPProxy registers itself in that tool's config so the assistant can talk to mcpproxy. A timestamped backup is created before any file is modified.
52+
Pick at least one AI tool. MCPProxy registers itself in that tool's config so the assistant can talk to mcpproxy. You'll see the exact change before anything is written, and a timestamped backup is created first.
5353
</p>
5454

5555
<div v-if="loadingClients" class="flex justify-center py-6">
@@ -1256,7 +1256,7 @@ const ClientRow: FunctionalComponent<
12561256
},
12571257
props.busy || props.previewBusy
12581258
? [h('span', { class: 'loading loading-spinner loading-xs' })]
1259-
: ['Connect']
1259+
: ['Review & connect']
12601260
),
12611261
]),
12621262
]

frontend/tests/unit/connect-modal.spec.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ describe('ConnectModal', () => {
154154
// A real one-click Connect button must be offered (not greyed out).
155155
const connectButton = wrapper.find('button.btn-primary.btn-xs')
156156
expect(connectButton.exists()).toBe(true)
157-
expect(connectButton.text()).toContain('Connect')
157+
expect(connectButton.text()).toContain('Review & connect')
158158

159159
// The bridge note must be surfaced to the user.
160160
expect(wrapper.text()).toContain('mcp-remote stdio bridge')
@@ -187,7 +187,7 @@ describe('ConnectModal', () => {
187187
// Fresh install: no config file yet, but the bridge Connect must still appear.
188188
const connectButton = wrapper.find('button.btn-primary.btn-xs')
189189
expect(connectButton.exists()).toBe(true)
190-
expect(connectButton.text()).toContain('Connect')
190+
expect(connectButton.text()).toContain('Review & connect')
191191
expect(wrapper.text()).not.toContain('Config not found')
192192
})
193193

@@ -293,7 +293,7 @@ describe('ConnectModal', () => {
293293
// cursor is genuinely not connected -> Connect button still offered.
294294
const connectButtons = wrapper.findAll('button.btn-primary.btn-xs')
295295
expect(connectButtons.length).toBe(1)
296-
expect(connectButtons[0].text()).toContain('Connect')
296+
expect(connectButtons[0].text()).toContain('Review & connect')
297297
})
298298

299299
// Spec 075 (MCP-2833) US1: the stat-only listing reports access_state=unknown
@@ -327,7 +327,7 @@ describe('ConnectModal', () => {
327327
// Explicit, no-eager-read affordance to verify access on demand.
328328
expect(wrapper.find('[data-test="connect-check-access"]').exists()).toBe(true)
329329
// Connect remains offered.
330-
expect(wrapper.find('button.btn-primary.btn-xs').text()).toContain('Connect')
330+
expect(wrapper.find('button.btn-primary.btn-xs').text()).toContain('Review & connect')
331331
})
332332

333333
// Spec 075 US2: a permission-denied client surfaces a distinct, actionable

0 commit comments

Comments
 (0)