feat(mcp): 新增 MCP 服务基础设施,重构规则文件序号,新增 v1.3.0 工单文档
- 规则重组:全局/ 下 8 个规则合并为 6 个(01+02→01,05+06→04),序号顺延 - 新增项目规则 05-多入口功能同步规范(UI/语音入口覆盖检查) - 新增 MCP 服务基础设施:Mcp/ 目录(DI 注册、端点扩展、动态工具描述符)、单元测试 - v1.3.0 工单文档:03 系列(会议任务拆分)、04(富文本描述与附件管理) - MCP 接口与前端集成指南:docs/manual/08、09
This commit is contained in:
@@ -0,0 +1,389 @@
|
||||
# MCP 服务接口文档
|
||||
|
||||
> Hua.Todo MCP Server 接口规范,供外部系统(AI 客户端、第三方集成)通过 MCP 协议接入 Hua.Todo 待办项管理能力。
|
||||
|
||||
## 1. 概述
|
||||
|
||||
Hua.Todo 提供了基于 **Model Context Protocol (MCP)** 的服务端,允许外部 MCP 客户端通过 Streamable HTTP 传输协议发现并调用待办项管理工具。
|
||||
|
||||
### 1.1 协议与传输
|
||||
|
||||
| 项目 | 说明 |
|
||||
|---|---|
|
||||
| 协议版本 | MCP 2025-03-26(Streamable HTTP) |
|
||||
| 传输方式 | Streamable HTTP(无状态模式) |
|
||||
| 内容格式 | JSON-RPC 2.0 |
|
||||
| 端点路径 | `/mcp` |
|
||||
| 认证 | 暂无(本地模式);生产环境建议通过反向代理添加认证 |
|
||||
|
||||
### 1.2 服务端信息
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "Hua.Todo MCP Server",
|
||||
"version": "1.0.0"
|
||||
}
|
||||
```
|
||||
|
||||
### 1.3 连接地址
|
||||
|
||||
| 运行模式 | 默认地址 |
|
||||
|---|---|
|
||||
| Hua.Todo.Host(独立服务端) | `http://localhost:5173/mcp` |
|
||||
| MAUI / Avalonia(嵌入式) | `http://localhost:5057/mcp` |
|
||||
|
||||
> 实际端口以部署配置为准。
|
||||
|
||||
---
|
||||
|
||||
## 2. 接入方式
|
||||
|
||||
### 2.1 MCP 客户端配置示例
|
||||
|
||||
**Claude Desktop / Cursor / 其他 MCP 客户端** 配置文件(`mcp_servers.json` 或等效):
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"hua-todo": {
|
||||
"url": "http://localhost:5173/mcp",
|
||||
"transport": "streamable-http"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 2.2 手动调用示例(curl)
|
||||
|
||||
MCP 协议基于 JSON-RPC 2.0,可通过 HTTP POST 手动调用:
|
||||
|
||||
#### 初始化连接
|
||||
|
||||
```bash
|
||||
curl -X POST http://localhost:5173/mcp \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "MCP-Protocol-Version: 2025-03-26" \
|
||||
-d '{
|
||||
"jsonrpc": "2.0",
|
||||
"id": 1,
|
||||
"method": "initialize",
|
||||
"params": {
|
||||
"protocolVersion": "2025-03-26",
|
||||
"capabilities": {},
|
||||
"clientInfo": { "name": "my-client", "version": "1.0.0" }
|
||||
}
|
||||
}'
|
||||
```
|
||||
|
||||
#### 列出可用工具
|
||||
|
||||
```bash
|
||||
curl -X POST http://localhost:5173/mcp \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "MCP-Protocol-Version: 2025-03-26" \
|
||||
-d '{
|
||||
"jsonrpc": "2.0",
|
||||
"id": 2,
|
||||
"method": "tools/list",
|
||||
"params": {}
|
||||
}'
|
||||
```
|
||||
|
||||
#### 调用工具
|
||||
|
||||
```bash
|
||||
curl -X POST http://localhost:5173/mcp \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "MCP-Protocol-Version: 2025-03-26" \
|
||||
-d '{
|
||||
"jsonrpc": "2.0",
|
||||
"id": 3,
|
||||
"method": "tools/call",
|
||||
"params": {
|
||||
"name": "CreateTodo",
|
||||
"arguments": {
|
||||
"title": "完成项目报告",
|
||||
"priority": "High"
|
||||
}
|
||||
}
|
||||
}'
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. 工具清单
|
||||
|
||||
### 3.1 查询类工具
|
||||
|
||||
#### ListAllTodos
|
||||
|
||||
获取所有待办项列表(含已完成和未完成)。
|
||||
|
||||
| 参数 | 类型 | 必填 | 说明 |
|
||||
|---|---|---|---|
|
||||
| 无 | - | - | - |
|
||||
|
||||
**返回示例**:
|
||||
|
||||
```
|
||||
所有待办项(共 3 项):
|
||||
[1] 完成项目报告 | 优先级:High | 进行中
|
||||
[2] 购买办公用品 | 优先级:Medium | 已完成
|
||||
[3] 整理会议纪要 | 优先级:Low | 进行中
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
#### ListActiveTodos
|
||||
|
||||
获取未完成的待办项列表。
|
||||
|
||||
| 参数 | 类型 | 必填 | 说明 |
|
||||
|---|---|---|---|
|
||||
| 无 | - | - | - |
|
||||
|
||||
**返回示例**:
|
||||
|
||||
```
|
||||
未完成待办项(共 2 项):
|
||||
[1] 完成项目报告 | 优先级:High | 进行中
|
||||
[3] 整理会议纪要 | 优先级:Low | 进行中
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
#### ListCompletedTodos
|
||||
|
||||
获取已完成的待办项列表。
|
||||
|
||||
| 参数 | 类型 | 必填 | 说明 |
|
||||
|---|---|---|---|
|
||||
| 无 | - | - | - |
|
||||
|
||||
---
|
||||
|
||||
#### GetTodoById
|
||||
|
||||
根据 ID 获取单个待办项详情(含子任务)。
|
||||
|
||||
| 参数 | 类型 | 必填 | 说明 |
|
||||
|---|---|---|---|
|
||||
| `id` | `int` | 是 | 待办项 ID |
|
||||
|
||||
**返回示例**:
|
||||
|
||||
```json
|
||||
{
|
||||
"id": 1,
|
||||
"title": "完成项目报告",
|
||||
"priority": "High",
|
||||
"isCompleted": false,
|
||||
"createdAt": "2026-06-16T08:30:00Z",
|
||||
"updatedAt": "2026-06-16T08:30:00Z",
|
||||
"parentTaskId": null,
|
||||
"subTasks": [
|
||||
{
|
||||
"id": 4,
|
||||
"title": "收集数据",
|
||||
"priority": "Medium",
|
||||
"isCompleted": true,
|
||||
"createdAt": "2026-06-16T08:35:00Z",
|
||||
"updatedAt": "2026-06-16T10:00:00Z",
|
||||
"parentTaskId": 1,
|
||||
"subTasks": []
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
**未找到时**:返回文本 `"未找到 ID 为 {id} 的待办项"`
|
||||
|
||||
---
|
||||
|
||||
#### ListSubTodos
|
||||
|
||||
获取指定父待办项下的所有子待办项。
|
||||
|
||||
| 参数 | 类型 | 必填 | 说明 |
|
||||
|---|---|---|---|
|
||||
| `parentTaskId` | `int` | 是 | 父待办项 ID |
|
||||
|
||||
---
|
||||
|
||||
### 3.2 写入类工具
|
||||
|
||||
#### CreateTodo
|
||||
|
||||
创建新的待办项。
|
||||
|
||||
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|
||||
|---|---|---|---|---|
|
||||
| `title` | `string` | 是 | - | 待办项标题 |
|
||||
| `priority` | `string` | 否 | `"Medium"` | 优先级:`Low` / `Medium` / `High` |
|
||||
| `parentTaskId` | `int` | 否 | `null` | 父待办项 ID(创建子任务时传入) |
|
||||
|
||||
**返回示例**:
|
||||
|
||||
```
|
||||
已创建待办项:
|
||||
{
|
||||
"id": 5,
|
||||
"title": "完成项目报告",
|
||||
"priority": "High",
|
||||
"isCompleted": false,
|
||||
"createdAt": "2026-06-16T10:00:00Z",
|
||||
"updatedAt": "2026-06-16T10:00:00Z",
|
||||
"parentTaskId": null,
|
||||
"subTasks": []
|
||||
}
|
||||
```
|
||||
|
||||
**优先级无效时**:返回文本 `"无效的优先级 'xxx',有效值为:Low、Medium、High"`
|
||||
|
||||
---
|
||||
|
||||
#### UpdateTodo
|
||||
|
||||
更新已有待办项的标题或优先级。
|
||||
|
||||
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|
||||
|---|---|---|---|---|
|
||||
| `id` | `int` | 是 | - | 待办项 ID |
|
||||
| `title` | `string` | 否 | `null` | 新标题 |
|
||||
| `priority` | `string` | 否 | `null` | 新优先级:`Low` / `Medium` / `High` |
|
||||
|
||||
**未找到时**:返回文本 `"未找到 ID 为 {id} 的待办项"`
|
||||
|
||||
---
|
||||
|
||||
#### ToggleTodoComplete
|
||||
|
||||
切换待办项的完成状态(已完成 ↔ 未完成)。
|
||||
|
||||
| 参数 | 类型 | 必填 | 说明 |
|
||||
|---|---|---|---|
|
||||
| `id` | `int` | 是 | 待办项 ID |
|
||||
|
||||
**返回示例**:
|
||||
|
||||
```
|
||||
已切换完成状态:
|
||||
{
|
||||
"id": 1,
|
||||
"title": "完成项目报告",
|
||||
"priority": "High",
|
||||
"isCompleted": true,
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
#### DeleteTodo
|
||||
|
||||
删除指定待办项。
|
||||
|
||||
| 参数 | 类型 | 必填 | 说明 |
|
||||
|---|---|---|---|
|
||||
| `id` | `int` | 是 | 待办项 ID |
|
||||
|
||||
**成功时**:返回文本 `"已删除待办项 {id}"`
|
||||
|
||||
**未找到时**:返回文本 `"未找到 ID 为 {id} 的待办项"`
|
||||
|
||||
---
|
||||
|
||||
## 4. 数据类型定义
|
||||
|
||||
### 4.1 TaskDto(待办项)
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
|---|---|---|
|
||||
| `id` | `int` | 唯一标识符 |
|
||||
| `title` | `string` | 标题 |
|
||||
| `priority` | `string` | 优先级枚举值:`"Low"` / `"Medium"` / `"High"` |
|
||||
| `isCompleted` | `bool` | 是否已完成 |
|
||||
| `createdAt` | `string` | 创建时间(ISO 8601 UTC) |
|
||||
| `updatedAt` | `string` | 更新时间(ISO 8601 UTC) |
|
||||
| `parentTaskId` | `int?` | 父待办项 ID(顶层任务为 null) |
|
||||
| `subTasks` | `TaskDto[]` | 子任务列表(递归结构) |
|
||||
|
||||
### 4.2 优先级枚举
|
||||
|
||||
| 值 | 说明 |
|
||||
|---|---|
|
||||
| `"Low"` | 低优先级 |
|
||||
| `"Medium"` | 中优先级(默认) |
|
||||
| `"High"` | 高优先级 |
|
||||
|
||||
---
|
||||
|
||||
## 5. 错误处理
|
||||
|
||||
MCP 工具调用中的错误通过返回文本内容表达(而非 MCP 协议级错误),常见情况:
|
||||
|
||||
| 场景 | 返回内容 |
|
||||
|---|---|
|
||||
| 待办项不存在 | `"未找到 ID 为 {id} 的待办项"` |
|
||||
| 优先级值无效 | `"无效的优先级 'xxx',有效值为:Low、Medium、High"` |
|
||||
| 列表为空 | `"没有{label}"` |
|
||||
|
||||
MCP 协议级错误(如方法不存在、参数格式错误)遵循 JSON-RPC 2.0 标准:
|
||||
|
||||
```json
|
||||
{
|
||||
"jsonrpc": "2.0",
|
||||
"id": 1,
|
||||
"error": {
|
||||
"code": -32600,
|
||||
"message": "Invalid Request"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. 与 HTTP API 的对照
|
||||
|
||||
MCP 工具与原有 HTTP Dynamic API 的对应关系:
|
||||
|
||||
| MCP 工具 | HTTP API | 说明 |
|
||||
|---|---|---|
|
||||
| `ListAllTodos` | `GET /api/task` | 获取全部 |
|
||||
| `ListActiveTodos` | `GET /api/task/active` | 获取未完成 |
|
||||
| `ListCompletedTodos` | `GET /api/task/completed` | 获取已完成 |
|
||||
| `GetTodoById` | `GET /api/task/{id}` | 按 ID 查询 |
|
||||
| `CreateTodo` | `POST /api/task` | 创建 |
|
||||
| `UpdateTodo` | `PUT /api/task` | 更新 |
|
||||
| `ToggleTodoComplete` | `PATCH /api/task/{id}/toggle` | 切换完成 |
|
||||
| `DeleteTodo` | `DELETE /api/task/{id}` | 删除 |
|
||||
| `ListSubTodos` | `GET /api/task/{parentTaskId}/subtasks` | 子任务 |
|
||||
|
||||
> 两套 API 共享同一 `ITaskService` 实现,数据完全一致,可根据场景选择使用。
|
||||
|
||||
---
|
||||
|
||||
## 7. 安全建议(生产部署)
|
||||
|
||||
1. **网络隔离**:MCP 端点默认无认证,建议仅在可信网络内暴露,或通过反向代理添加 API Key / Bearer Token 认证
|
||||
2. **CORS 限制**:生产环境应将 CORS 策略从 `AllowAll` 改为指定来源
|
||||
3. **HTTPS**:生产环境必须启用 HTTPS
|
||||
4. **速率限制**:建议对 MCP 端点添加请求速率限制
|
||||
|
||||
---
|
||||
|
||||
## 8. 常见问题
|
||||
|
||||
### Q: MCP 端点和 HTTP API 可以同时使用吗?
|
||||
可以。两者共享相同的数据源和服务层,不存在冲突。
|
||||
|
||||
### Q: Streamable HTTP 无状态模式下支持服务端通知吗?
|
||||
不支持。无状态模式下服务端无法向客户端主动推送通知。如需通知能力,需改为有状态模式(`Stateless = false`),但需要会话亲和。
|
||||
|
||||
### Q: 如何验证 MCP 服务是否正常运行?
|
||||
发送 `initialize` 请求(见 2.2 节),若返回服务端信息则表示正常。
|
||||
|
||||
---
|
||||
|
||||
**文档版本**:1.0.0
|
||||
**最后更新**:2026-06-16
|
||||
@@ -0,0 +1,210 @@
|
||||
# MCP 前端集成指南(Hua.Todo 内部使用)
|
||||
|
||||
> 适用范围:Hua.Todo 前端(Vue / TypeScript)团队,通过 MCP 协议与后端交互。
|
||||
> 外部系统接入请参阅 [08-MCP服务接口文档.md](./08-MCP服务接口文档.md)。
|
||||
|
||||
---
|
||||
|
||||
## 一、背景
|
||||
|
||||
v1.3.0 起,Hua.Todo 后端在原有 Dynamic API(`/api/*`)基础上,新增了 MCP(Model Context Protocol)服务端点。前端可根据场景选择:
|
||||
|
||||
| 通道 | 端点 | 适用场景 |
|
||||
|---|---|---|
|
||||
| Dynamic API | `/api/task/*` | WebView 内常规 CRUD、已有逻辑兼容 |
|
||||
| MCP | `/mcp` | AI 辅助、语音指令、外部工具集成 |
|
||||
|
||||
两套通道共享同一 `ITaskService` 业务层,数据一致。
|
||||
|
||||
---
|
||||
|
||||
## 二、连接方式
|
||||
|
||||
### 2.1 嵌入式模式(MAUI / Avalonia + WebView)
|
||||
|
||||
```
|
||||
MCP 端点:http://localhost:5057/mcp
|
||||
```
|
||||
|
||||
当前嵌入式宿主**仅暴露 Dynamic API**,MCP 端点在嵌入式模式下同样可用(`AddMcpServerServices` 已注册)。
|
||||
|
||||
### 2.2 Host 模式(独立服务端)
|
||||
|
||||
```
|
||||
MCP 端点:http://<host>:5173/mcp
|
||||
```
|
||||
|
||||
开发环境通过 Vite proxy 可直接访问 `/mcp`。
|
||||
|
||||
---
|
||||
|
||||
## 三、前端 MCP 客户端选型
|
||||
|
||||
### 3.1 推荐方案:`@modelcontextprotocol/sdk`
|
||||
|
||||
官方 TypeScript MCP SDK,支持 Streamable HTTP 传输。
|
||||
|
||||
```bash
|
||||
npm install @modelcontextprotocol/sdk
|
||||
```
|
||||
|
||||
### 3.2 连接示例
|
||||
|
||||
```typescript
|
||||
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
|
||||
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamablehttp.js";
|
||||
|
||||
const transport = new StreamableHTTPClientTransport(
|
||||
new URL("http://localhost:5057/mcp")
|
||||
);
|
||||
|
||||
const client = new Client({
|
||||
name: "hua-todo-frontend",
|
||||
version: "1.3.0",
|
||||
});
|
||||
|
||||
await client.connect(transport);
|
||||
|
||||
// 列出所有可用工具
|
||||
const tools = await client.listTools();
|
||||
console.log("可用工具:", tools);
|
||||
|
||||
// 调用工具
|
||||
const result = await client.callTool({
|
||||
name: "ListActiveTodos",
|
||||
arguments: {},
|
||||
});
|
||||
console.log("未完成待办项:", result);
|
||||
```
|
||||
|
||||
### 3.3 封装建议
|
||||
|
||||
在 `src/Hua.Todo.Web/src/api/` 下新增 `mcpClient.ts`:
|
||||
|
||||
```typescript
|
||||
// src/api/mcpClient.ts
|
||||
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
|
||||
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamablehttp.js";
|
||||
|
||||
const MCP_BASE_URL = window.__API_BASE_URL__
|
||||
? window.__API_BASE_URL__.replace("/api", "/mcp")
|
||||
: "/mcp";
|
||||
|
||||
let client: Client | null = null;
|
||||
|
||||
/** 获取或创建 MCP 客户端单例 */
|
||||
export async function getMcpClient(): Promise<Client> {
|
||||
if (!client) {
|
||||
const transport = new StreamableHTTPClientTransport(
|
||||
new URL(MCP_BASE_URL, window.location.origin)
|
||||
);
|
||||
client = new Client({
|
||||
name: "hua-todo-frontend",
|
||||
version: "1.3.0",
|
||||
});
|
||||
await client.connect(transport);
|
||||
}
|
||||
return client;
|
||||
}
|
||||
|
||||
/** 断开 MCP 连接 */
|
||||
export async function disconnectMcp(): Promise<void> {
|
||||
if (client) {
|
||||
await client.close();
|
||||
client = null;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 四、工具调用映射(MCP vs Dynamic API)
|
||||
|
||||
| 业务操作 | Dynamic API | MCP Tool | MCP 参数 |
|
||||
|---|---|---|---|
|
||||
| 获取所有待办项 | `GET /api/task` | `ListAllTodos` | 无 |
|
||||
| 获取未完成待办项 | `GET /api/task/active` | `ListActiveTodos` | 无 |
|
||||
| 获取已完成待办项 | `GET /api/task/completed` | `ListCompletedTodos` | 无 |
|
||||
| 获取单个待办项 | `GET /api/task/{id}` | `GetTodoById` | `id: number` |
|
||||
| 创建待办项 | `POST /api/task` | `CreateTodo` | `title, priority?, parentTaskId?` |
|
||||
| 更新待办项 | `PUT /api/task` | `UpdateTodo` | `id, title?, priority?` |
|
||||
| 切换完成状态 | `PATCH /api/task/{id}/toggle` | `ToggleTodoComplete` | `id: number` |
|
||||
| 删除待办项 | `DELETE /api/task/{id}` | `DeleteTodo` | `id: number` |
|
||||
| 获取子待办项 | `GET /api/task/{pid}/subtasks` | `ListSubTodos` | `parentTaskId: number` |
|
||||
|
||||
---
|
||||
|
||||
## 五、返回格式差异
|
||||
|
||||
### Dynamic API 返回
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"data": [{ "id": 1, "title": "...", ... }],
|
||||
"message": "",
|
||||
"errors": []
|
||||
}
|
||||
```
|
||||
|
||||
### MCP Tool 返回
|
||||
|
||||
MCP 工具返回 `string` 类型,分两种格式:
|
||||
|
||||
**列表类**(可读文本):
|
||||
```
|
||||
未完成待办项(共 2 项):
|
||||
[1] 完成报告 | 优先级:High | 进行中
|
||||
[3] 买菜 | 优先级:Low | 进行中 | 父ID:2
|
||||
```
|
||||
|
||||
**单条/创建/更新类**(JSON):
|
||||
```json
|
||||
{
|
||||
"id": 1,
|
||||
"title": "完成报告",
|
||||
"priority": "High",
|
||||
"isCompleted": false,
|
||||
"createdAt": "2026-06-16T08:00:00Z",
|
||||
"updatedAt": "2026-06-16T08:00:00Z",
|
||||
"parentTaskId": null,
|
||||
"subTasks": []
|
||||
}
|
||||
```
|
||||
|
||||
> 前端如果需要结构化数据,建议仍使用 Dynamic API;MCP 通道主要用于 AI 场景和文本交互。
|
||||
|
||||
---
|
||||
|
||||
## 六、典型场景
|
||||
|
||||
### 6.1 AI 对话式操作
|
||||
|
||||
用户通过 AI 助手(接入 MCP 的 LLM 客户端)用自然语言操作待办项:
|
||||
|
||||
```
|
||||
用户:帮我看看还有哪些事没做完
|
||||
AI:→ 调用 ListActiveTodos
|
||||
AI:您有 2 项未完成的待办:[1] 完成报告 [3] 买菜
|
||||
|
||||
用户:把"完成报告"标为已完成
|
||||
AI:→ 调用 ToggleTodoComplete(id=1)
|
||||
AI:已将"完成报告"标记为完成
|
||||
```
|
||||
|
||||
### 6.2 语音指令
|
||||
|
||||
语音 → STT → 文本 → LLM 解析意图 → MCP Tool 调用 → TTS 播报结果。
|
||||
|
||||
### 6.3 外部工具集成
|
||||
|
||||
IDE 插件、自动化脚本等通过 MCP 协议直接操作待办项,无需理解 HTTP API 细节。
|
||||
|
||||
---
|
||||
|
||||
## 七、注意事项
|
||||
|
||||
1. **MCP 无状态模式**:当前配置为 Stateless,不支持服务端→客户端通知;如需实时推送仍走 Dynamic API 或 WebSocket
|
||||
2. **CORS**:开发环境 `AllowAll` 策略已覆盖 `/mcp`;生产环境需按需配置
|
||||
3. **认证**:当前 MCP 端点未接入认证中间件;如需鉴权,需在 `MapMcpServer` 后追加 `.RequireAuthorization()`
|
||||
4. **生命周期**:MCP 客户端连接为长连接,建议在组件 `onUnmounted` 时调用 `disconnectMcp()`
|
||||
Reference in New Issue
Block a user