Skip to content

Lamp

The patch-bay status light, and the only thing in Switchboard that glows. Shows whether a server is patched in, healthy, or carrying a call right now.

FeedbackServer-rendered

Examples

States

Six states, one meaning each. Live and error carry a halo; routed glows once; off is hollow.

Light
OffIdleLiveRoutedWarningFailing
Dark
OffIdleLiveRoutedWarningFailing
Example
<Lamp state="off" label="Off" showLabel />
<Lamp state="idle" label="Idle" showLabel />
<Lamp state="live" label="Live" showLabel />
<Lamp state="routed" label="Routed" showLabel />
<Lamp state="warn" label="Warning" showLabel />
<Lamp state="error" label="Failing" showLabel />

What each state means

Pick the state from what an agent would experience, not from the last HTTP status alone.

OffNot patched in. Added but disabled; agents cannot see its tools.IdlePatched in and reachable, but no calls yet or none lately.LiveConnected and healthy. The last check and the last calls succeeded.RoutedA call just went through. One 2s glow, then it settles to live.WarningDegraded: slow, some calls failing, or a token expiring soon.FailingNot answering, or auth failed. Agents get errors for its tools.
Example
{states.map(({ state, label, meaning }) => (
  <>
    <Lamp state={state} label={label} showLabel />
    <span>{meaning}</span>
  </>
))}

In a server list

The label says why, not just the state: "Token expires in 2 days" beats "Warning". On narrow rows hide the label; it is still read out.

GitHub

mcp.github.com

Routed just now

Linear

mcp.linear.app

Live

Sentry

mcp.sentry.dev

Token expires in 2 days

Notion

mcp.notion.com

Auth failed

Postgres (staging)

localhost:5433

Off
Example
<Card>
  {servers.map((server) => (
    <div class="server-row">
      <Stack gap="1">
        <Text weight="medium">{server.name}</Text>
        <Text size="xs" tone="ink-3" mono>{server.host}</Text>
      </Stack>
      <Lamp state={server.state} label={server.label} showLabel />
    </div>
  ))}
</Card>

Dot only

Without showLabel the label is visually hidden but still read. Echo it in a tooltip when the dot sits on a focusable control.

Linear is live

Linear

Example
<Inline gap="2">
  <Lamp state="live" label="Linear is live" />
  <Text>Linear</Text>
</Inline>
<Tooltip content="Sentry: token expires in 2 days">
  <Button variant="ghost" size="sm">
    <Lamp state="warn" label="Token expires in 2 days" />
    Sentry
  </Button>
</Tooltip>

Usage

Usage
import { Lamp } from '@switchboard/ui'

<Lamp state={server.lamp} label={server.statusText} showLabel />

Props

Every component also takes mix, for css() and mixins applied after its own style.

Lamp

Lamp props
PropTypeDefaultDescription
state*'off' | 'idle' | 'live' | 'routed' | 'warn' | 'error'–off: not patched in. idle: patched, quiet. live: connected and healthy. routed: a call just went through (one-shot glow). warn: degraded or auth expiring. error: failing.
label*string–What the state means for this server. Always rendered; visually hidden unless showLabel.
showLabelboolean–Show the label next to the dot (13px, ink-2).
align'center' | 'text''center'text: top-align the dot with the first line of a wrapping row (a name cell), using the row’s line height.
mixMix–Extra css() or mixins.

Also accepts every <span> attribute.

Accessibility

  • Colour is never the only signal: `label` is required and is always in the DOM, visually hidden without showLabel. The dot itself is aria-hidden.
  • Off is a hollow ring, not just a grey dot, so it differs from idle by shape as well as colour.
  • A Lamp is not a live region. When a state change must be announced, also raise a toast or put the row in a role="status" container.
  • The routed glow runs once (2s) and is skipped under prefers-reduced-motion.

Guidance

Do

  • Use a Lamp for live server and connection state; it is the only element allowed to glow.
  • Write the label as the reason: "Token expires in 2 days", "Auth failed".
  • Re-render with routed when a call passes through, then fall back to live.

Don’t

  • Use a Lamp as decoration, a bullet, or for things that are not live state (use a Badge with dot).
  • Invent new colours or make it blink; the six states are the whole vocabulary.
  • Put two lamps on one row.