Skip to content

Commit 1c1013c

Browse files
authored
Merge pull request #248 from docker/cm/ui-mcp-client-change
Update MCP Client UI slightly
2 parents fd4923c + 96f09e5 commit 1c1013c

File tree

3 files changed

+135
-105
lines changed

3 files changed

+135
-105
lines changed

src/extension/ui/src/components/CatalogGrid.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,7 @@ export const CatalogGrid: React.FC<CatalogGridProps> = ({ appProps }) => {
7878
>
7979
<Typography variant="h3">Docker MCP Toolkit</Typography>
8080
<Typography sx={{ color: 'text.secondary' }}>
81-
Browse the Docker MCP Catalog and connect Dockerized MCP servers to
82-
your favorite MCP Client
81+
Find and connect your favorite tools to MCP clients. One click away.
8382
</Typography>
8483
</Stack>
8584
{hasOutOfCatalog && (

src/extension/ui/src/components/tabs/ToolCatalog.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ const ToolCatalog: React.FC<ToolCatalogProps> = ({
3838
})
3939
: filteredItems;
4040
}, [catalogItems, search, sort]);
41+
4142
const enabled = all.filter((item) => item.registered);
4243

4344
return (

src/extension/ui/src/components/tabs/YourClients.tsx

Lines changed: 133 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {
77
Card,
88
CardContent,
99
CardHeader,
10+
Chip,
1011
CircularProgress,
1112
Collapse,
1213
Divider,
@@ -15,6 +16,7 @@ import {
1516
ListItem,
1617
ListItemText,
1718
Stack,
19+
Theme,
1820
Typography
1921
} from '@mui/material';
2022
import { useEffect, useState } from 'react';
@@ -24,6 +26,7 @@ import ContinueIcon from '../../assets/continue.svg';
2426
import CursorIcon from '../../assets/cursor.svg';
2527
import GordonIcon from '../../assets/gordon-icon.png';
2628
import { CATALOG_LAYOUT_SX, DOCKER_MCP_COMMAND } from '../../Constants';
29+
import { LinkOff, LinkOffOutlined, LinkOutlined } from '@mui/icons-material';
2730

2831
// Initialize the Docker Desktop client
2932
const client = createDockerDesktopClient();
@@ -39,6 +42,19 @@ const iconMap = {
3942
'Continue.dev': ContinueIcon,
4043
};
4144

45+
const ConnectButtonStyle = (theme: Theme) => ({
46+
fontSize: '14px',
47+
p: 1,
48+
alignItems: 'center',
49+
justifyContent: 'center',
50+
[theme.breakpoints.down('sm')]: {
51+
p: '2px',
52+
'& .MuiTypography-root': {
53+
fontSize: '12px',
54+
},
55+
},
56+
});
57+
4258
const MCPClientSettings = ({ appProps }: MCPClientSettingsProps) => {
4359
// Extract all the values we need from appProps
4460
const { mcpClientStates, updateMCPClientStates } = appProps;
@@ -127,6 +143,7 @@ function ClientSetting({
127143
mcpClientState: any;
128144
appProps: any;
129145
}) {
146+
130147
const [expanded, setExpanded] = useState(false);
131148

132149
// Extract all the values we need from appProps
@@ -149,78 +166,75 @@ function ClientSetting({
149166
/>
150167
)
151168
}
152-
title={<Typography variant="subtitle2">{name}</Typography>}
169+
title={<Typography variant="subtitle2">{name}{mcpClientState.exists ? '' : <Chip sx={{ ml: 1 }} label="Not detected" color="error" size="small" />}</Typography>}
153170
subheader={
154-
mcpClientState.exists ? (
155-
<Typography
156-
variant="body2"
157-
sx={{
158-
color: 'text.secondary',
159-
alignItems: 'center',
160-
display: 'flex',
161-
cursor: 'pointer',
162-
}}
163-
onClick={() => setExpanded(!expanded)}
164-
>
165-
Manual configuration
166-
{expanded ? (
171+
< Typography
172+
variant="body2"
173+
sx={{
174+
color: 'text.secondary',
175+
alignItems: 'center',
176+
display: 'flex',
177+
cursor: 'pointer',
178+
}}
179+
onClick={() => setExpanded(!expanded)}
180+
>
181+
Manual configuration
182+
{
183+
expanded ? (
167184
<KeyboardArrowDownIcon fontSize="small" />
168185
) : (
169186
<KeyboardArrowRightIcon fontSize="small" />
170-
)}
171-
</Typography>
172-
) : (
173-
<Typography
174-
variant="body2"
175-
sx={{
176-
color: 'text.secondary',
177-
}}
178-
>
179-
Client not installed
180-
</Typography>
181-
)
187+
)
188+
}
189+
</Typography >
182190
}
183191
action={
184-
<Stack direction="row" spacing={1}>
185-
{mcpClientState.exists && mcpClientState.configured && (
186-
<Button
187-
onClick={async () => {
188-
setButtonsLoading({
189-
...buttonsLoading,
190-
[name]: true,
191-
});
192-
try {
193-
await disconnectClient(name);
194-
} finally {
192+
< Stack direction="row" spacing={1} >
193+
{
194+
mcpClientState.exists && mcpClientState.configured && (
195+
<Button
196+
color="warning"
197+
onClick={async () => {
195198
setButtonsLoading({
196199
...buttonsLoading,
197-
[name]: false,
200+
[name]: true,
198201
});
202+
try {
203+
await disconnectClient(name);
204+
} finally {
205+
setButtonsLoading({
206+
...buttonsLoading,
207+
[name]: false,
208+
});
209+
}
210+
}}
211+
disabled={
212+
buttonsLoading[name] ||
213+
Boolean(mcpClientState.preventAutoConnectMessage)
199214
}
200-
}}
201-
disabled={buttonsLoading[name]}
202-
color="warning"
203-
size="small"
204-
>
205-
<Stack direction="row" alignItems="center" spacing={1}>
206-
{(buttonsLoading[name] && (
207-
<>
208-
<Typography sx={{ fontSize: 12, width: 70 }}>
209-
Connect
210-
</Typography>
211-
<CircularProgress size={12} />
212-
</>
213-
)) || (
214-
<Typography sx={{ fontSize: 12, width: 90 }}>
215-
Disconnect
216-
</Typography>
217-
)}
218-
</Stack>
219-
</Button>
220-
)}
215+
>
216+
<Stack direction="row" alignItems="center" spacing={1} sx={ConnectButtonStyle}>
217+
{(buttonsLoading[name] && (
218+
<>
219+
<LinkOutlined />
220+
<Typography>
221+
Connect
222+
</Typography>
223+
<CircularProgress size={12} />
224+
</>
225+
)) || (
226+
<>
227+
<LinkOffOutlined />
228+
<Typography>
229+
Disconnect
230+
</Typography>
231+
</>
232+
)}
233+
</Stack>
234+
</Button>
235+
)}
221236
{mcpClientState.exists && !mcpClientState.configured && (
222237
<Button
223-
sx={{ fontSize: 12 }}
224238
onClick={async () => {
225239
setButtonsLoading({
226240
...buttonsLoading,
@@ -231,70 +245,86 @@ function ClientSetting({
231245
} finally {
232246
setButtonsLoading({
233247
...buttonsLoading,
234-
[name]: false,
248+
[name]: true,
235249
});
250+
try {
251+
await connectClient(name);
252+
} finally {
253+
setButtonsLoading({
254+
...buttonsLoading,
255+
[name]: false,
256+
});
257+
}
236258
}
237259
}}
238260
disabled={buttonsLoading[name]}
239261
color="primary"
240262
size="small"
241263
>
242-
<Stack direction="row" alignItems="center" spacing={1}>
264+
<Stack direction="row" alignItems="center" spacing={1} sx={ConnectButtonStyle}>
243265
{(buttonsLoading[name] && (
244266
<>
245-
<Typography sx={{ fontSize: 12, width: 70 }}>
267+
<LinkOffOutlined />
268+
<Typography>
246269
Disconnect
247270
</Typography>
248271
<CircularProgress size={12} />
249272
</>
250273
)) || (
251-
<Typography sx={{ fontSize: 12, width: 90 }}>
252-
Connect
253-
</Typography>
274+
<>
275+
<LinkOutlined />
276+
<Typography>
277+
Connect
278+
</Typography>
279+
</>
254280
)}
255281
</Stack>
256282
</Button>
257283
)}
258-
{!mcpClientState.exists && (
259-
<Button
260-
sx={{ fontSize: 12 }}
261-
size="small"
262-
disabled
263-
onClick={async () => {
264-
setButtonsLoading({
265-
...buttonsLoading,
266-
[name]: true,
267-
});
268-
try {
269-
await connectClient(name);
270-
} finally {
284+
{
285+
!mcpClientState.exists && (
286+
<Button
287+
size="small"
288+
variant="outlined"
289+
onClick={async () => {
271290
setButtonsLoading({
272291
...buttonsLoading,
273-
[name]: false,
292+
[name]: true,
274293
});
275-
}
276-
}}
277-
>
278-
<Stack direction="row" alignItems="center" spacing={1}>
279-
{(buttonsLoading[name] && (
280-
<>
281-
<Typography sx={{ fontSize: 12, width: 70 }}>
282-
Disconnect
283-
</Typography>
284-
<CircularProgress size={12} />
285-
</>
286-
)) || (
287-
<Typography sx={{ fontSize: 12, width: 90 }}>
288-
Connect
289-
</Typography>
290-
)}
291-
</Stack>
292-
</Button>
293-
)}
294-
</Stack>
294+
try {
295+
await connectClient(name);
296+
} finally {
297+
setButtonsLoading({
298+
...buttonsLoading,
299+
[name]: true,
300+
});
301+
}
302+
}}
303+
>
304+
<Stack direction="row" alignItems="center" spacing={1} sx={ConnectButtonStyle}>
305+
{(buttonsLoading[name] && (
306+
<>
307+
<LinkOffOutlined />
308+
<Typography>
309+
Attempt disconnect
310+
</Typography>
311+
<CircularProgress size={12} />
312+
</>
313+
)) || (
314+
<>
315+
<LinkOutlined />
316+
<Typography>
317+
Attempt connection
318+
</Typography>
319+
</>
320+
)}
321+
</Stack>
322+
</Button>
323+
)}
324+
</Stack >
295325
}
296326
/>
297-
<Collapse in={expanded} timeout="auto" unmountOnExit>
327+
<Collapse in={expanded} timeout="auto" unmountOnExit >
298328
<CardContent>
299329
<Stack direction="column" justifyContent="center" spacing={1}>
300330
<Stack direction="row" alignItems="center" spacing={1}>
@@ -345,8 +375,8 @@ function ClientSetting({
345375
)}
346376
</List>
347377
</CardContent>
348-
</Collapse>
349-
</Card>
378+
</Collapse >
379+
</Card >
350380
);
351381
}
352382

0 commit comments

Comments
 (0)