UI组件库

一个基于Lit构建的可组合Web组件库,专为MCP(Model Context Protocol)接口设计,支持主题定制、暗黑模式和树摇优化。

  • by brukhabtu
  • TypeScript
  • 本地部署
  • 更新于
在 GitHub 查看 brukhabtu/mcp-components

使用说明

@mcp/ui组件

用于MCP UI的可组合web组件库 点亮设计用于与MCP(模型上下文协议)接口轻松组合和集成。

特性

  • 🧩 可组合 -设计用于无缝协作的组件
  • 🎨 主题可 -CSS自定义属性,便于自定义
  • 🌙 深色模式 -内置深色主题支持
  • ♿ 可访问的 -ARIA属性和键盘导航
  • 📦 树可以摇动 -只导入您需要的内容
  • 🔧 TypeScript -包括完整的类型定义

安装

npm install @mcp/ui-components

快速开始

// Import all components
import '@mcp/ui-components';

// Or import specific components
import '@mcp/ui-components/primitives';
import '@mcp/ui-components/layout';
import '@mcp/ui-components/feedback';
import '@mcp/ui-components/data-display';
<mcp-button variant="primary">Click Me</mcp-button>
<mcp-card>
  <span slot="header">Card Title</span>
  <p>Card content goes here.</p>
</mcp-card>

组件

原语

组件 描述
<mcp-button> 带变体的按钮:主要、次要、轮廓、重影、破坏性
<mcp-input> 带有标签、辅助文本和错误状态的文本输入
<mcp-textarea> 支持自动调整大小的多行文本输入
<mcp-badge> 具有多种变体的身份徽章
<mcp-icon> 内置图标的SVG图标组件

布局

组件 描述
<mcp-stack> 灵活的堆叠布局(垂直/水平)
<mcp-vstack> 垂直堆叠(简写)
<mcp-hstack> 水平堆叠(简写)
<mcp-card> 带页眉/页脚插槽的卡片容器
<mcp-grid> CSS网格布局组件
<mcp-divider> 带可选标签的视觉分隔符

反馈

组件 描述
<mcp-alert> 警报消息(信息、成功、警告、错误)
<mcp-spinner> 加载旋转器
<mcp-loading> 加载带有消息的覆盖层
<mcp-progress> 进度条(确定/不确定)
<mcp-skeleton> 正在加载占位符

数据显示

组件 描述
<mcp-code> 带有语法高亮提示的代码块
<mcp-kv> 键值列表容器
<mcp-kv-item> 键值对项目
<mcp-list> 列出容器
<mcp-list-item> 带插槽的列表项
<mcp-empty> 空状态占位符

例子

按钮变体

<mcp-button>Primary</mcp-button>
<mcp-button variant="secondary">Secondary</mcp-button>
<mcp-button variant="outline">Outline</mcp-button>
<mcp-button variant="ghost">Ghost</mcp-button>
<mcp-button variant="destructive">Delete</mcp-button>
<mcp-button loading>Loading...</mcp-button>

表单布局

<mcp-vstack gap="var(--mcp-space-4)">
  <mcp-input 
    label="Email" 
    type="email" 
    placeholder="Enter your email"
    helper="We'll never share your email"
  ></mcp-input>
  
  <mcp-input 
    label="API Key" 
    type="password"
    error="Invalid API key format"
  ></mcp-input>
  
  <mcp-button>Submit</mcp-button>
</mcp-vstack>

带有动作的卡片

<mcp-card>
  <span slot="header">
    <mcp-hstack justify="between" align="center">
      <strong>MCP Server</strong>
      <mcp-badge variant="success">Connected</mcp-badge>
    </mcp-hstack>
  </span>
  
  <mcp-kv>
    <mcp-kv-item key="Server" value="weather-mcp"></mcp-kv-item>
    <mcp-kv-item key="Tools" value="3 available"></mcp-kv-item>
  </mcp-kv>
  
  <mcp-hstack slot="footer" justify="end" gap="var(--mcp-space-2)">
    <mcp-button variant="ghost">Disconnect</mcp-button>
    <mcp-button>View Tools</mcp-button>
  </mcp-hstack>
</mcp-card>

加载状态

<!-- Spinner -->
<mcp-spinner size="lg"></mcp-spinner>

<!-- Progress bar -->
<mcp-progress value="65" label="Uploading..." show-value></mcp-progress>

<!-- Indeterminate progress -->
<mcp-progress indeterminate label="Processing..."></mcp-progress>

<!-- Skeleton loading -->
<mcp-card>
  <mcp-hstack gap="var(--mcp-space-3)">
    <mcp-skeleton width="3rem" height="3rem" circle></mcp-skeleton>
    <mcp-vstack style="flex: 1;">
      <mcp-skeleton width="60%" height="1rem"></mcp-skeleton>
      <mcp-skeleton-text lines="2"></mcp-skeleton-text>
    </mcp-vstack>
  </mcp-hstack>
</mcp-card>

MCP工具响应显示

<mcp-card>
  <span slot="header">
    <mcp-hstack justify="between">
      <strong>get_weather</strong>
      <mcp-badge variant="success">Success</mcp-badge>
    </mcp-hstack>
  </span>
  
  <mcp-code language="json">
{
  "location": "San Francisco",
  "temperature": 68,
  "conditions": "Partly Cloudy"
}
  </mcp-code>
</mcp-card>

主题化

组件使用CSS自定义属性进行主题化。在您的应用程序中覆盖它们:

:root {
  /* Primary color */
  --mcp-color-primary: #6366f1;
  --mcp-color-primary-hover: #4f46e5;
  
  /* Spacing */
  --mcp-space-4: 1rem;
  
  /* Border radius */
  --mcp-radius-md: 0.375rem;
  
  /* Typography */
  --mcp-font-family: 'Inter', system-ui, sans-serif;
}

/* Dark mode */
[data-theme="dark"] {
  --mcp-color-background: #0f172a;
  --mcp-color-foreground: #f8fafc;
}

控制器

用于管理组件状态的可重用逻辑:

异步控制器

import { AsyncController } from '@mcp/ui-components/controllers';

class MyElement extends LitElement {
  private _async = new AsyncController<Data>(this);

  async fetchData() {
    await this._async.run(async (signal) => {
      const response = await fetch('/api/data', { signal });
      return response.json();
    });
  }

  render() {
    if (this._async.isPending) return html`<mcp-spinner></mcp-spinner>`;
    if (this._async.isError) return html`<mcp-alert variant="error">${this._async.error}</mcp-alert>`;
    return html`<div>${this._async.data}</div>`;
  }
}

FormFieldController

import { FormFieldController, validators } from '@mcp/ui-components/controllers';

class MyForm extends LitElement {
  private _email = new FormFieldController(this, [
    validators.required(),
    validators.email(),
  ]);

  render() {
    return html`
      <mcp-input
        label="Email"
        .value=${this._email.value}
        .error=${this._email.showError ? this._email.error : ''}
        @mcp-input=${(e) => this._email.setValue(e.detail.value)}
        @blur=${() => this._email.touch()}
      ></mcp-input>
    `;
  }
}

发展

# Install dependencies
npm install

# Start dev server
npm run dev

# Build
npm run build

# Type check
npm run build

许可证

麻省理工学院