---
outline: [1, 3]
---

# MCP Server Picker 插件选择器

MCP Server Picker 组件是一个用于展示和管理插件的组件，支持已安装插件和插件市场两个标签页，可以进行插件的添加、删除和启用/禁用操作。

## 基础用法

<demo vue="../../demos/mcp-server-picker/basic-usage.vue" />

### 插件添加状态

市场插件支持三种添加状态，提供更好的用户体验：

- **idle**: 未添加状态，显示"添加"按钮，用户可以点击添加
- **loading**: 添加中状态，显示"添加中"按钮，按钮不可点击，适用于网络请求等异步操作
- **added**: 已添加状态，显示"已添加"按钮，按钮不可点击

通过 `addState` 属性控制插件的添加状态，开发者可以在添加插件的异步过程中动态更新状态，提升用户体验。

#### 状态控制示例

```typescript
const handlePluginAdd = (plugin: PluginInfo) => {
  const targetPlugin = marketPlugins.value.find((p) => p.id === plugin.id)!
  
  // 设置为加载状态
  targetPlugin.addState = 'loading'
  
  // 异步添加插件
  addPluginToServer(plugin)
    .then(() => {
      // 添加成功
      targetPlugin.addState = 'added'
      // 添加到已安装列表
      installedPlugins.value.push(newPlugin)
    })
    .catch(() => {
      // 添加失败，重置为idle状态，用户可以重新尝试
      targetPlugin.addState = 'idle'
    })
}
```

## 弹出方式

> MCP Server Picker 组件支持两种弹出方式， 即 `Fixed` 模式和 `Drawer` 模式，通过 `popupConfig` 配置对象统一管理

<demo vue="../../demos/mcp-server-picker/popup-config.vue" />


## Props

| 属性                       | 类型                      | 默认值                                                            | 说明                                         |
| -------------------------- | ------------------------- | ----------------------------------------------------------------- | -------------------------------------------- |
| installedPlugins           | `PluginInfo[]`            | `[]`                                                              | 已安装插件列表                               |
| marketPlugins              | `PluginInfo[]`            | `[]`                                                              | 市场插件列表                                 |
| enableSearch               | `boolean`                 | `true`                                                            | 是否启用搜索功能                             |
| searchPlaceholder          | `string`                  | `'搜索插件'`                                                      | 搜索框占位符                                 |
| enableMarketCategoryFilter | `boolean`                 | `true`                                                            | 是否启用市场分类筛选功能                     |
| marketCategoryOptions      | `MarketCategoryOption[]`  | `[]`                                                              | 市场分类选项列表                             |
| marketCategoryPlaceholder  | `string`                  | `'按照分类筛选'`                                                  | 分类筛选下拉框占位符                         |
| visible                    | `boolean`                 | `false`                                                           | 是否显示整个组件面板（支持 v-model:visible） |
| activeCount                | `number`                  | -                                                                 | 激活插件数量（支持 v-model:activeCount）     |
| defaultActiveTab           | `'installed' \| 'market'` | `'installed'`                                                     | 默认激活的标签页                             |
| showInstalledTab           | `boolean`                 | `true`                                                            | 是否显示已安装标签页                         |
| showMarketTab              | `boolean`                 | `true`                                                            | 是否显示市场标签页                           |
| installedTabTitle          | `string`                  | `'已安装插件'`                                                    | 已安装标签页标题                             |
| marketTabTitle             | `string`                  | `'市场'`                                                          | 市场标签页标题                               |
| popupConfig                | `PopupConfig`             | `{ type: 'fixed', position: {}, drawer: { direction: 'right' } }` | 弹出配置对象                                 |
| title                      | `string`                  | `'插件'`                                                          | 组件标题                                     |
| showCustomAddButton        | `boolean`                 | `true`                                                            | 是否显示自定义添加按钮                       |
| customAddButtonText        | `string`                  | `'自定义添加'`                                                    | 自定义添加按钮文本                           |
| allowPluginToggle          | `boolean`                 | `true`                                                            | 是否允许切换插件状态                         |
| allowToolToggle            | `boolean`                 | `true`                                                            | 是否允许切换工具状态                         |
| allowPluginDelete          | `boolean`                 | `true`                                                            | 是否允许删除插件                             |
| allowPluginAdd             | `boolean`                 | `true`                                                            | 是否允许添加插件                             |
| loading                    | `boolean`                 | `false`                                                           | 已安装插件加载状态                           |
| marketLoading              | `boolean`                 | `false`                                                           | 市场插件加载状态                             |

## Events

| 事件名                   | 说明                   | 回调参数                                                |
| ------------------------ | ---------------------- | ------------------------------------------------------- |
| market-category-change   | 市场分类筛选变化       | `(category: string)`                                    |
| installedSearchFn        | 已添加插件搜索函数     | `(query: string, item: PluginInfo) => boolean`          |
| marketSearchFn           | 市场插件搜索函数       | `(query: string, item: PluginInfo) => boolean`          |
| update:visible           | 面板显示状态变化       | `(visible: boolean)`                                    |
| update:activeCount       | 激活插件数量变化       | `(count: number)`                                       |
| tab-change               | 标签页切换             | `(activeTab: 'installed' \| 'market')`                  |
| plugin-toggle            | 插件启用/禁用          | `(plugin: PluginInfo, enabled: boolean)`                |
| plugin-delete            | 删除插件               | `(plugin: PluginInfo)`                                  |
| plugin-add               | 市场插件添加           | `(plugin: PluginInfo)`                                  |
| plugin-create            | 插件创建               | `(type: 'form' \| 'code', data: PluginCreationData)`    |
| tool-toggle              | 工具启用/禁用          | `(plugin: PluginInfo, toolId: string, enabled: boolean)` |
| refresh                  | 刷新请求               | `(tab: 'installed' \| 'market')`                        |

## Types

**PluginInfo**

插件信息类型：

```typescript
type PluginAddState = 'idle' | 'loading' | 'added'

interface PluginInfo {
  id: string              // 插件唯一标识
  name: string            // 插件名称
  icon: string            // 插件图标URL
  description: string     // 插件描述
  enabled: boolean       // 是否启用
  expanded?: boolean      // 是否展开
  tools: PluginTool[]    // 工具列表
  addState?: PluginAddState // 市场插件添加状态(可选): 'idle' - 未添加, 'loading' - 添加中, 'added' - 已添加
  category?: string       // 插件分类(可选，用于市场分类筛选)
}
```

**PluginTool**

插件工具类型：

```typescript
interface PluginTool {
  id: string              // 工具唯一标识
  name: string            // 工具名称
  description: string     // 工具描述
  enabled: boolean        // 是否启用
}
```

**MarketCategoryOption**

市场分类选项类型：

```typescript
interface MarketCategoryOption {
  value: string           // 分类值
  label: string           // 分类显示名称
}
```

**PluginFormData**

表单方式添加插件数据类型：

```typescript
interface PluginFormData {
  name: string            // 插件名称
  description: string     // 插件描述
  type: 'sse' | 'streamableHttp'  // 插件类型, sse 或 streamableHttp
  url: string             // 插件 URL
  headers: string         // 请求头（JSON 格式字符串）
  thumbnail?: File | null // 缩略图文件（可选）
}
```

**PluginCreationData**

PluginCreationData 类型是 PluginFormData 或 string 的联合类型，用于表示插件创建的数据。

```typescript
type PluginCreationData = PluginFormData | string
```

**PopupConfig**

弹窗配置类型：

```typescript
interface PopupConfig {
  type: 'fixed' | 'drawer'
  // fixed模式配置
  position?: {
    top?: string | number
    left?: string | number
    right?: string | number
    bottom?: string | number
  }
  // drawer模式配置
  drawer?: {
    direction: 'left' | 'right'
  }
}
```

<!--@include: ./mcp-add-form.md-->
