MCP Server Card

One MCP server: what it is, how it is attached, and what it brought with it. Leads with the transport and the actual command line, because a server named “filesystem” tells you nothing and `--root /` tells you everything.

src/components/ui/mcp-server-card.tsx

About

From the component's own source, where it was written.

One MCP server: what it is, how it is attached, and what it brought with it.

An MCP client is only as trustworthy as the servers plugged into it, and the fact that decides that is the **command line**, not the name. A server called "filesystem" tells you nothing; npx @acme/fs-server --root / tells you it can read your home directory.

Which is why the target gets its own full-width row and **wraps instead of truncating**. The first version of this card put it in a single-line ellipsis beside the name, which cut off --root / — hiding exactly the argument the card exists to surface. A component that claims one field is the important one and then clips it is arguing against itself.

The body is a fixed three-band layout — identity, target, capabilities — with the footer pinned to the bottom by mt-auto. Cards in a grid then line their footers up even when one of them is carrying an error block and the others are not, which is the usual way a card grid goes ragged.

Status is a dot and a word rather than a badge, so it does not compete with the transport chip beside it; capability counts are shown for all three kinds with the zeroes dimmed, because "no prompts" is a real answer and hiding it makes an absent capability indistinguishable from an unreported one.

Install

npx astralyx-ui add mcp-server-card

Usage

import { McpServerCard } from '@/components/ui/mcp-server-card'

<McpServerCard
  name="filesystem"
  target="npx -y @modelcontextprotocol/server-filesystem /Users/ada/work"
  transport="stdio"
  status="connected"
  capabilities={{ tools: 8, resources: 214, prompts: 0 }}
  onReconnect={reconnect}
/>

Composer

Change the props and the source below follows.

filesystem

Connectedstdio
npx -y @modelcontextprotocol/server-filesystem /Users/ada/work
8 tools214 resources0 prompts
0.6.2 · MCP 2025-06-18

linear

Failedsse
https://mcp.linear.app/sse

Handshake failed: 401 Unauthorized. The stored token has expired.

 
Props
tsx
<McpServerCard
  name="filesystem"
  target="npx -y @modelcontextprotocol/server-filesystem /Users/ada/work"
  transport="stdio"
  status="connected"
  capabilities={{ tools: 8, resources: 214, prompts: 0 }}
/>

Examples

A fleet, one of them broken

API

Generated from the source, so it cannot fall behind the code. One table per exported component, then hooks, functions and types.

McpServerCard

One MCP server: what it is, how it is attached, and what it brought with it.

Extends Omit<ComponentProps<'div'>, 'onSelect'>.

PropTypeDefaultDescription
namestringrequired—
targetstring—The command line or endpoint, on its own full-width row, wrapping rather than truncating. The first version clipped it mid-flag — a card that claims one field matters most and then cuts it off is arguing against itself.
transportMcpTransport'stdio'How it is attached. Shown as a badge beside the status.
statusMcpStatus'connected'A failed server stays in the list — silently dropping it is how a client quietly loses half its capabilities with no indication why.
protocolVersionstring—Protocol version negotiated at handshake.
versionstring—The server's own version string.
capabilities{ tools?: number; resources?: number; prompts?: number }—Counted per kind, never totalled — forty resources is a search index; three tools might be a shell. Zeroes stay visible but dimmed, so an absent capability does not look like an unreported one.
errorReactNode—Handshake or runtime failure, rendered prominently rather than as a tooltip.
onReconnect() => void—Renders the retry. Stops propagation, so it does not also select the card.
reconnectLabelstring'Reconnect'—
copyTargetbooleantrueA copy button beside the command. Off for an endpoint nobody needs on the clipboard.
copyLabelstring'Copy command'—
actionsReactNode—Trailing slot in the header — a menu, a disable switch.
selectedbooleanfalse—
onSelect() => void——
statusLabelsPartial<Record<McpStatus, string>>——
capabilityLabels{ tools?: string; resources?: string; prompts?: string }——

Types

TypeDefinitionDescription
McpTransport
'stdio' | 'http' | 'sse' | 'websocket'
—
McpStatus
'connected' | 'connecting' | 'disconnected' | 'error'
—

Behaviour

TopicDetailDescription
alignmenth-full + mt-auto footerFooters line up across a grid even when only some cards carry an error block — the usual way a card grid goes ragged.