Skip to content

Commit 2364b4a

Browse files
committed
style: improve style of remote servers, enable to remove from stack in the dropdown of a server
1 parent da568db commit 2364b4a

File tree

3 files changed

+82
-26
lines changed

3 files changed

+82
-26
lines changed

index.html

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
/>
1717
<meta property="og:type" content="website" />
1818
<meta property="og:site_name" content="MCP Registry UI" />
19+
<meta property="og:image" content="https://vemonet.github.io/mcp-registry/mcp.svg" />
20+
<meta property="og:logo" content="https://vemonet.github.io/mcp-registry/mcp.svg" />
1921
<script type="application/ld+json">
2022
{
2123
"@context": "https://schema.org",

src/App.tsx

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -189,14 +189,14 @@ export default function App() {
189189
}
190190
};
191191

192-
/** Download config file */
193-
const downloadConfig = (configType: 'vscode' | 'cursor') => {
192+
/** Download `mcp.json` config file */
193+
const downloadMcpJsonConfig = (configType: 'vscode' | 'cursor') => {
194194
const config = generateStackConfig(configType);
195195
const blob = new Blob([config], { type: 'application/json' });
196196
const url = URL.createObjectURL(blob);
197197
const a = document.createElement('a');
198198
a.href = url;
199-
a.download = configType === 'vscode' ? 'mcp-settings.json' : 'cursor-config.json';
199+
a.download = 'mcp.json';
200200
document.body.appendChild(a);
201201
a.click();
202202
document.body.removeChild(a);
@@ -381,15 +381,15 @@ export default function App() {
381381
{/* Download stack config dropdown */}
382382
<div className="border-t pt-2 mt-2 space-y-1">
383383
<DropdownMenuItem
384-
onClick={() => downloadConfig('vscode')}
384+
onClick={() => downloadMcpJsonConfig('vscode')}
385385
className="flex items-center gap-2 cursor-pointer"
386386
>
387387
<Download className="h-4 w-4" />
388388
<img src={VscodeLogo} alt="VSCode" className="h-4 w-4" />
389389
Download VSCode <code>mcp.json</code>
390390
</DropdownMenuItem>
391391
<DropdownMenuItem
392-
onClick={() => downloadConfig('cursor')}
392+
onClick={() => downloadMcpJsonConfig('cursor')}
393393
className="flex items-center gap-2 cursor-pointer"
394394
>
395395
<Download className="h-4 w-4" />
@@ -398,7 +398,7 @@ export default function App() {
398398
alt="Cursor"
399399
className="h-4 w-4 [filter:invert(0)] dark:[filter:invert(1)]"
400400
/>
401-
Download Cursor config
401+
Download Cursor <code>mcp.json</code>
402402
</DropdownMenuItem>
403403
<DropdownMenuItem
404404
onClick={() => setStack([])}
@@ -433,8 +433,13 @@ export default function App() {
433433
</TooltipTrigger>
434434
<TooltipContent>
435435
<p>
436-
<a href="https://github.com/vemonet/mcp-registry" target="_blank" rel="noopener noreferrer">
437-
https://github.com/vemonet/mcp-registry
436+
<a
437+
href="https://github.com/vemonet/mcp-registry"
438+
target="_blank"
439+
rel="noopener noreferrer"
440+
className="hover:text-muted-foreground"
441+
>
442+
🔗 github.com/vemonet/mcp-registry
438443
</a>
439444
</p>
440445
</TooltipContent>
@@ -523,7 +528,12 @@ export default function App() {
523528
}`}
524529
>
525530
{/* MCP Server card to display a server */}
526-
<ServerCard item={item} addToStack={addToStack} isInStack={isInStack} />
531+
<ServerCard
532+
item={item}
533+
addToStack={addToStack}
534+
removeFromStack={removeFromStack}
535+
isInStack={isInStack}
536+
/>
527537
</Card>
528538
))}
529539
</div>

src/components/server-card.tsx

Lines changed: 61 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import {
1212
Plus,
1313
Container,
1414
Settings,
15+
Delete,
1516
} from 'lucide-react';
1617

1718
import {
@@ -44,10 +45,12 @@ export const ServerCard = ({
4445
item,
4546
addToStack,
4647
isInStack,
48+
removeFromStack,
4749
}: {
4850
item: ServerItem;
4951
addToStack: (serverName: string, type: 'remote' | 'package', data: any, index: number) => void;
5052
isInStack: (serverName: string, type: 'remote' | 'package', index: number) => boolean;
53+
removeFromStack: (serverName: string, type: 'remote' | 'package', index: number) => void;
5154
}) => {
5255
const [copiedUrl, setCopiedUrl] = useState<string | null>(null);
5356

@@ -83,7 +86,9 @@ export const ServerCard = ({
8386
</div>
8487
</TooltipTrigger>
8588
<TooltipContent>
86-
<p>Status: {itemMeta.status}</p>
89+
<p>
90+
<span className="text-muted-foreground">☑️ Status:</span> {itemMeta.status}
91+
</p>
8792
</TooltipContent>
8893
</Tooltip>
8994
)}
@@ -105,9 +110,15 @@ export const ServerCard = ({
105110
</div>
106111
</TooltipTrigger>
107112
<TooltipContent>
108-
<p>📅 Published at {new Date(itemMeta.publishedAt).toLocaleString('fr-FR')}</p>
113+
<p>
114+
<span className="text-muted-foreground">📅 Published at</span>{' '}
115+
{new Date(itemMeta.publishedAt).toLocaleString('fr-FR')}
116+
</p>
109117
{itemMeta?.updatedAt && itemMeta.updatedAt != itemMeta.publishedAt && (
110-
<p>♻️ Updated at {new Date(itemMeta.updatedAt).toLocaleString('fr-FR')}</p>
118+
<p>
119+
<span className="text-muted-foreground">♻️ Updated at</span>{' '}
120+
{new Date(itemMeta.updatedAt).toLocaleString('fr-FR')}
121+
</p>
111122
)}
112123
</TooltipContent>
113124
</Tooltip>
@@ -136,8 +147,13 @@ export const ServerCard = ({
136147
</TooltipTrigger>
137148
<TooltipContent>
138149
<p>
139-
<a target="_blank" rel="noopener noreferrer" href={item.server.repository.url}>
140-
{item.server.repository.url}
150+
<a
151+
href={item.server.repository.url}
152+
className="hover:text-muted-foreground"
153+
target="_blank"
154+
rel="noopener noreferrer"
155+
>
156+
🔗 {item.server.repository.url}
141157
</a>
142158
</p>
143159
</TooltipContent>
@@ -150,11 +166,10 @@ export const ServerCard = ({
150166
</CardHeader>
151167
{(item.server.remotes && item.server.remotes.length > 0) ||
152168
(item.server.packages && item.server.packages.length > 0) ? (
153-
<CardContent className="pt-0 space-y-2">
169+
<CardContent className="pt-0 space-y-2 space-x-2">
154170
{/* <ServerAccessSection server={item.server} addToStack={addToStack} isInStack={isInStack} /> */}
155171
{/* Packages Section */}
156172
{item.server.packages &&
157-
item.server.packages.length > 0 &&
158173
item.server.packages.map(
159174
(pkg, pkgIndex) => {
160175
// NOTE: Disabled package/remotes list wrapper, it was cluttering the UI too much
@@ -196,7 +211,12 @@ export const ServerCard = ({
196211
{pkg.registryBaseUrl && (
197212
<p>
198213
<span className="text-muted-foreground">📘 Registry:</span>{' '}
199-
<a href={pkg.registryBaseUrl} target="_blank" rel="noopener noreferrer">
214+
<a
215+
href={pkg.registryBaseUrl}
216+
className="hover:text-muted-foreground"
217+
target="_blank"
218+
rel="noopener noreferrer"
219+
>
200220
{pkg.registryBaseUrl}
201221
</a>
202222
</p>
@@ -269,12 +289,23 @@ export const ServerCard = ({
269289
</Tooltip>
270290
<DropdownMenuContent align="start" onClick={(e) => e.stopPropagation()}>
271291
<DropdownMenuItem
272-
onClick={() => addToStack(item.server.name, 'package', pkg, pkgIndex)}
292+
onClick={() => {
293+
return isInStack(item.server.name, 'package', pkgIndex)
294+
? removeFromStack(item.server.name, 'package', pkgIndex)
295+
: addToStack(item.server.name, 'package', pkg, pkgIndex);
296+
}}
273297
className="flex items-center gap-2"
274-
disabled={isInStack(item.server.name, 'package', pkgIndex)}
298+
// disabled={isInStack(item.server.name, 'package', pkgIndex)}
275299
>
276-
<Plus className="h-3.5 w-3.5" />
277-
{isInStack(item.server.name, 'package', pkgIndex) ? 'In your Stack' : 'Add to your Stack'}
300+
{isInStack(item.server.name, 'package', pkgIndex) ? (
301+
<>
302+
<Delete className="h-3.5 w-3.5" /> Remove from Stack
303+
</>
304+
) : (
305+
<>
306+
<Plus className="h-3.5 w-3.5" /> Add to your Stack
307+
</>
308+
)}
278309
</DropdownMenuItem>
279310
{packageUrl && (
280311
<DropdownMenuItem asChild>
@@ -380,9 +411,12 @@ export const ServerCard = ({
380411
) : remote.type.includes('http') ? (
381412
<Rss className="h-4 w-4 text-muted-foreground flex-shrink-0" />
382413
) : (
414+
// <Router className="h-4 w-4 text-muted-foreground flex-shrink-0" />
383415
<Link2 className="h-4 w-4 text-muted-foreground flex-shrink-0" />
384416
)}
385-
<span className="break-all font-mono text-muted-foreground">{remote.url}</span>
417+
<span className="break-all font-mono text-muted-foreground">
418+
{remote.url.replace('https://', '')}
419+
</span>
386420
{remote.headers && Object.keys(remote.headers).length > 0 && (
387421
<Settings className="h-3 w-3 text-blue-300 flex-shrink-0" />
388422
)}
@@ -434,12 +468,22 @@ export const ServerCard = ({
434468
</Tooltip>
435469
<DropdownMenuContent align="start" onClick={(e) => e.stopPropagation()}>
436470
<DropdownMenuItem
437-
onClick={() => addToStack(item.server.name, 'remote', remote, remoteIndex)}
471+
onClick={() => {
472+
return isInStack(item.server.name, 'remote', remoteIndex)
473+
? removeFromStack(item.server.name, 'remote', remoteIndex)
474+
: addToStack(item.server.name, 'remote', remote, remoteIndex);
475+
}}
438476
className="flex items-center gap-2"
439-
disabled={isInStack(item.server.name, 'remote', remoteIndex)}
440477
>
441-
<Plus className="h-3.5 w-3.5" />
442-
{isInStack(item.server.name, 'remote', remoteIndex) ? 'In your Stack' : 'Add to your Stack'}
478+
{isInStack(item.server.name, 'remote', remoteIndex) ? (
479+
<>
480+
<Delete className="h-3.5 w-3.5" /> Remove from Stack
481+
</>
482+
) : (
483+
<>
484+
<Plus className="h-3.5 w-3.5" /> Add to your Stack
485+
</>
486+
)}
443487
</DropdownMenuItem>
444488
<DropdownMenuItem onClick={() => copyToClipboard(remote.url)} className="flex items-center gap-2">
445489
<Copy className="h-3.5 w-3.5" />

0 commit comments

Comments
 (0)