27 KiB
MCP Client Vue - 版本发布记录
v1.0.0
重构时间: 2025-10-12
🎯 初始发布
核心特性
- MCP客户端基础功能 - 支持Model Context Protocol
- 双传输协议 - HTTP和SSE(Server-Sent Events)传输
- Vue 3 + TypeScript - 现代化前端技术栈
- Naive UI组件库 - 美观的用户界面
- Pinia状态管理 - 响应式数据流
基础功能
- 服务器连接管理
- 工具调用执行
- 资源获取支持
- 提示词管理
- 基本的错误处理
技术实现
- 前后端分离架构
- RESTful API设计
- 实时双向通信
- 模块化组件设计
- TypeScript类型安全
📋 项目结构
mcp-client-vue/
├── src/ # 后端服务
│ ├── server/ # Express服务器
│ └── types/ # TypeScript类型
├── web/ # Vue前端应用
│ ├── src/ # Vue组件和服务
│ ├── public/ # 静态资源
│ └── dist/ # 构建输出
└── docs/ # 项目文档
🎯 设计理念
- 用户友好 - 直观的操作界面
- 开发者友好 - 清晰的代码结构
- 可扩展性 - 模块化架构设计
- 跨平台 - 基于Web技术实现
下载和安装
系统要求
- Node.js 18.0+
- 现代浏览器(Chrome 90+, Firefox 88+, Safari 14+)
快速开始
# 克隆项目
git clone [repository-url]
cd mcp-client-vue
# 安装依赖
cd web && npm install
# 启动开发服务器
npm run dev
# 访问应用
open http://localhost:5173
生产构建
# 构建项目
npm run build
# 预览构建
npm run preview
支持和反馈
MCP Client Vue - 让MCP集成变得简单高效 🚀
v1.0.1
重构时间: 2025-10-14
🎉 重大改进
基于v1.0.0的深度优化版本,全面提升了用户体验和系统稳定性。
🚀 核心功能
- 完善的服务器管理系统
- 支持HTTP和SSE双传输协议
- 可视化连接状态管理
- 自动重连机制(页面刷新恢复连接)
- 智能URL地址转换(0.0.0.0 → localhost)
🛠️ 主要修复
- ✅ 编辑按钮响应 - 修复点击无响应问题
- ✅ 连接协议 - 修复HTTP 406和SSE 404错误
- ✅ 界面显示 - 修复模态框空白页问题
- ✅ 表单数据 - 修复字段不填充问题
- ✅ 状态持久化 - 修复页面刷新断连问题
🎨 用户体验
- 优化模态框尺寸(90vw宽度,最大1200px)
- 改进表单验证和错误提示
- 实时连接状态指示
- 详细的操作日志和调试信息
🏗️ 技术栈升级
- Vue 3.4.15
- TypeScript 5.3.3
- Naive UI 2.43.1
- vue-tsc 2.0.6(从1.8.25升级)
📦 发布内容
# 安装和启动
cd web && npm install
npm run dev
🔧 配置要求
HTTP服务器
{
"name": "HTTP服务器",
"url": "http://localhost:3100",
"type": "http"
}
SSE服务器
{
"name": "SSE服务器",
"url": "http://localhost:3200/sse",
"type": "sse"
}
⚠️ 已知问题
- TypeScript类型错误47个(不影响功能)
- 使用
npm run build:skip-check跳过类型检查
v1.0.2
发布时间: 2025-10-14
🎯 重大功能:MCP 工具调用集成
本版本实现了完整的 MCP 工具调用功能,AI 可以智能调用 MCP 服务器提供的工具并整合结果。
✨ 核心功能
🔧 智能工具调用
- AI 自动识别何时需要调用工具
- 支持 OpenAI Function Calling 协议
- 兼容多个 AI 服务商(OpenAI、火山引擎、阿里云等)
- 完整的多轮对话支持(AI → Tool → AI)
🔄 流式工具执行
- 实时显示工具调用进度
- 流式体验不中断
- 友好的状态提示:
- 🔧 正在调用工具: [工具名]...
- ✅ 工具执行完成
- ❌ 工具执行失败: [错误信息]
- 🤖 正在生成回复...
📋 工具格式转换
- MCP 工具 → OpenAI Function 格式
- 自动提取 inputSchema 作为 parameters
- 支持完整的 JSON Schema 定义
🛠️ 技术实现
服务层改进
MCPClientService.getTools()- 获取工具列表chatService.convertToolsToOpenAIFormat()- 格式转换chatService.executeToolCalls()- 工具执行逻辑modelServiceManager.sendChatRequestStream()- 增强工具参数支持
流式解析增强
- SSE 流中检测
tool_calls - 累积多个流片段中的工具调用数据
- 正确拼接
function.argumentsJSON 字符串 - 返回完整的工具调用数组
消息格式支持
// 工具调用消息
{
role: 'assistant',
content: '',
tool_calls: [{
id: '...',
type: 'function',
function: { name: '...', arguments: '{}' }
}]
}
// 工具结果消息
{
tool_call_id: '...',
role: 'tool',
name: 'tool_name',
content: '{...}'
}
📦 使用方式
- 配置 AI 服务 - 在"模型服务"中添加支持函数调用的 AI
- 连接 MCP 服务器 - 在"MCP 设置"中添加工具服务器
- 选择模型和 MCP - 在对话界面选择
- 开始对话 - AI 会自动调用相关工具
💡 使用示例
用户: "查询今天北京的天气"
系统: 🔧 正在调用工具: get_weather...
✅ 工具执行完成
🤖 正在生成回复...
AI: "根据天气数据,今天北京晴天,温度 15-25°C,
空气质量良好,适合户外活动。"
🐛 Bug 修复
- ✅ 修复 MCPClientService 类型导入问题
- ✅ 修复 types.ts 和 types/index.ts 路径冲突
- ✅ 修复 modelServiceManager 返回类型
- ✅ 修复未使用变量警告
🔧 技术细节
修改的文件
/web/src/services/chatService.ts- 工具调用主逻辑/web/src/services/modelServiceManager.ts- 工具参数支持/web/src/services/MCPClientService.ts- 工具列表获取
新增方法
MCPClientService.getTools(serverId)- 获取服务器工具chatService.convertToolsToOpenAIFormat()- 格式转换chatService.executeToolCalls()- 执行工具调用
改进方法
modelServiceManager.sendChatRequestStream()- 支持 tools 参数modelServiceManager.makeChatRequestStream()- 检测和收集 tool_calls
🎯 设计亮点
- 无缝集成 - 不改变现有对话流程
- 错误恢复 - 工具调用失败不影响对话继续
- 类型安全 - 完整的 TypeScript 类型定义
- 性能优化 - 流式处理保持响应速度
- 用户友好 - 清晰的进度提示
⚙️ 配置要求
AI 服务要求
- 支持 OpenAI Function Calling 格式
- 推荐:OpenAI GPT-3.5+, GPT-4+
- 兼容:火山引擎、阿里云等 OpenAI 兼容服务
MCP 服务器要求
- 实现
tools/list接口 - 实现
tools/call接口 - 提供标准的 inputSchema (JSON Schema)
📚 相关文档
🚀 升级指南
# 拉取最新代码
git pull origin main
# 安装依赖(如有更新)
cd web && npm install
# 启动开发服务器
npm run dev
🔜 下一步计划
- 工具调用历史记录
- 工具执行超时控制
- 批量工具调用优化
- 工具调用权限管理
- 工具调用性能监控
v1.0.2 - AI + MCP 工具调用,让对话更智能! 🚀🔧
v1.0.3
发布时间: 2025-10-15
重大功能:停止生成 & UI 优化
本版本实现了完整的停止生成功能,参考 Cherry Studio 的 PAUSED 状态设计,提供更好的用户体验。
核心功能
智能停止生成
- 点击停止按钮立即中断 AI 回复(响应时间 < 100ms)
- 保留已生成的内容,标记为"已停止"状态
- 区分用户主动停止和系统错误
- 停止后可立即继续对话
UI 体验优化
- 按钮文字从"确认"改为"发送"
- 停止后显示黄色"已停止"标签(而非红色"发送失败")
- 停止的消息可以复制、重新生成、删除
- 实时状态反馈(发送中 → 已停止 → 可操作)
状态管理增强
- 新增
paused消息状态 - 新增
paused流式事件类型 - 完整的 AbortController 信号传递链
- 流读取循环实时检查中止信号
技术实现
按钮事件修复
- 修复点击事件绑定问题(从三元表达式改为函数调用)
- 运行时动态判断状态,而非编译时
// Before: @click="store.state.isSending ? handleStopGeneration : handleSendMessage"
// After: @click="handleButtonClick"
const handleButtonClick = () => {
if (store.state.isSending) {
handleStopGeneration()
} else {
handleSendMessage()
}
}
中止信号传递链
UI (点击停止)
↓ handleStopGeneration()
↓ store.stopGeneration()
↓ abortController.abort()
↓ chatService.sendMessageStream(signal)
↓ modelServiceManager.makeChatRequestStream(signal)
↓ while循环检查 signal.aborted
↓ reader.cancel() + 抛出 AbortError
↓ 状态设置为 'paused'
↓ UI 更新显示"已停止"
流读取中止检查
while (true) {
// 关键:每次读取前检查中止信号
if (signal?.aborted) {
console.log('检测到中止信号,停止读取流')
reader.cancel()
throw new DOMException('用户中止操作', 'AbortError')
}
const { done, value } = await reader.read()
if (done) break
// 处理数据...
}
错误处理优化
catch (error) {
const isAborted = error instanceof Error && error.name === 'AbortError'
if (isAborted) {
// 用户主动停止 - 标记为 paused,保留内容
assistantMessage.status = 'paused'
assistantMessage.error = undefined
onChunk({ type: 'paused', messageId: assistantMessage.id })
// 关键:更新消息列表,触发 UI 刷新
state.messages = [...chatService.getMessages(currentTopicId)]
} else {
// 真实错误 - 标记为 error
assistantMessage.status = 'error'
assistantMessage.error = error.message
}
}
Bug 修复
Emoji 测试
为验证发布脚本对 emoji 的处理(例如某些 emoji 属于 4 字节 unicode,可能触发服务器端 collation 问题),在此插入若干 emoji 供测试:
- 表情类:😄 😂 😭 🥳
- 物品/动作:🚀 🧪 🔧 📝
- 动物/自然:🐛 🐶 🌳
- 标志/符号:🏷️ ✅ ❌ 🔣
示例行(包含中文和 emoji):
测试:本行包含中文与 emoji,目的是验证脚本对 emoji 的过滤与回退逻辑。示例 emoji:😄 🚀 🐛 🧪 🏷️
- 修复按钮点击无响应问题(事件绑定错误)
- 修复停止后仍显示"发送中..."状态
- 修复停止后消息列表不更新
- 修复 AbortError 被错误标记为失败
- 修复按钮文字显示"确认"而非"发送"
修改的文件
类型定义
/web/src/types/chat.ts- MessageStatus 添加
'paused'类型 - StreamEvent 添加
'paused'事件类型
- MessageStatus 添加
UI 组件
/web/src/components/Chat/ChatLayout.vue- 修复按钮点击事件绑定
- 按钮文字改为"发送"
- 添加"已停止"状态标签显示
- paused 状态消息显示操作按钮
服务层
-
/web/src/services/chatService.ts- 区分 AbortError 和其他错误
- 设置 paused 状态和事件
-
/web/src/services/modelServiceManager.ts- 流读取循环中检查 signal.aborted
- 调用 reader.cancel() 中止读取
- 正确处理 AbortError
状态管理
/web/src/stores/chatStore.ts- 在 catch 块中更新消息列表
- 确保 UI 显示最新状态
使用示例
1. 用户发送:"请详细介绍 Vue 3 的新特性"
2. AI 开始回复,显示"发送中..."
3. 用户点击"停止"按钮
4. 立即响应:
- 输出停止
- 标签变为"已停止"(黄色)
- 显示已生成的内容
- 显示操作按钮
5. 用户可以:
- 复制已生成的内容
- 重新生成完整回复
- 删除该消息
- 继续发送新消息
设计亮点
- 参考 Cherry Studio - 借鉴成熟产品的设计理念
- 立即响应 - 停止操作 < 100ms 响应
- 内容保留 - 部分生成的内容依然有价值
- 状态区分 - paused vs error,语义更清晰
- 完整操作 - 停止的消息仍可进行各种操作
- 信号传递 - 完整的中止信号链,确保可靠性
用户体验对比
修复前
- 点击停止无反应
- 继续显示"发送中..."
- 显示 loading 动画
- 按钮文字为"确认"
修复后
- 点击立即停止
- 显示"已停止"(黄色)
- 隐藏 loading 动画
- 按钮文字为"发送"
- 可以操作停止的消息
- 立即可继续对话
相关文档
STOP_GENERATION_SUMMARY.md- 修复总结STOP_GENERATION_FIX.md- 详细技术文档STOP_GENERATION_PATCH.md- 补充修复说明STOP_GENERATION_TEST.md- 测试指南STOP_GENERATION_VERIFY.md- 快速验证清单
升级指南
# 拉取最新代码
git pull origin main
# 安装依赖
cd web && npm install
# 启动开发服务器
npm run dev
# 测试停止功能
# 1. 发送消息
# 2. 在 AI 回复时点击"停止"
# 3. 验证显示"已停止"标签
# 4. 验证可以继续对话
验收标准
- 按钮点击有明显反应
- 流输出在 100ms 内停止
- 显示"已停止"而非"失败"
- 保留已生成内容
- 停止后可立即继续对话
- 可对停止的消息进行操作
- 无意外错误日志
下一步计划
- 停止后自动保存草稿
- 停止历史记录统计
- 批量停止多个会话
- 停止原因记录(用户主动/超时/错误)
- 性能监控和优化
v1.0.3 - 完美的停止体验,让对话更可控!
v2.0.0
重构时间: 2025-10-16
Phase 1: 核心服务拆分 (Day 1-2) ✅ 已完成
- ✅ Step 1: 创建服务目录结构
/web/src/services/chat/ - ✅ Step 2: 提取 MessageService - 消息 CRUD 操作(20+ 方法)
- ✅ Step 3: 提取 ConversationService - 对话管理(10+ 方法)
- ✅ Step 4: 创建统一日志系统 Logger (支持日志级别、命名空间、格式化)
- ✅ Step 5: 创建错误处理体系 AppError (ValidationError, NetworkError, APIError, ServiceError, StorageError + ErrorHandler)
- ✅ Step 6: 提取 StreamProcessor - 流式响应处理(性能监控、批量输出、工具集成)
- ✅ Step 7: 提取 ToolExecutor - 工具调用执行(递归调用链、错误处理)
- ✅ Step 8: 创建 ChatOrchestrator - 协调所有服务(话题管理、消息管理、流式发送、持久化 + togglePin/Favorite/Archive)
- ✅ Step 9: 更新 chatStore 使用新服务(已完成:chatService → chatOrchestrator)
- ⏸️ Step 10: 测试验证,确保无功能回归
✅ Phase 1 重构完成!旧的 chatService.ts (1147行) 已完全被新架构替代。
服务架构总结:
ChatOrchestrator (协调器)
├── MessageService (消息 CRUD)
├── ConversationService (对话管理)
├── StreamProcessor (流式处理)
└── ToolExecutor (工具执行)
工具层:
├── Logger (统一日志)
└── AppError + ErrorHandler (错误处理)
┌─────────────────────────────────────────────────────────┐
│ 用户界面层 (UI) │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ 聊天视图 │ │ 设置视图 │ │ 模型管理 │ │ MCP管理 │ │
│ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │
└─────────────────────────────────────────────────────────┘
↓ ↑
┌─────────────────────────────────────────────────────────┐
│ 状态管理层 (Pinia Stores) │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │chatStore │ │modelStore│ │ mcpStore │ │
│ └──────────┘ └──────────┘ └──────────┘ │
└─────────────────────────────────────────────────────────┘
↓ ↑
┌─────────────────────────────────────────────────────────┐
│ 业务服务层 (Services) │
│ ┌─────────────────────────────────────────────────────┐│
│ │ ChatOrchestrator (协调器) ││
│ │ ┌────────────┐ ┌────────────┐ ┌────────────┐ ││
│ │ │ Message │ │Conversation│ │ Stream │ ││
│ │ │ Service │ │ Service │ │ Processor │ ││
│ │ └────────────┘ └────────────┘ └────────────┘ ││
│ │ ┌────────────┐ ││
│ │ │ Tool │ ││
│ │ │ Executor │ ││
│ │ └────────────┘ ││
│ └─────────────────────────────────────────────────────┘│
│ ┌──────────────┐ ┌──────────────┐ │
│ │ModelService │ │MCPClientSvc │ │
│ │ Manager │ │ │ │
│ └──────────────┘ └──────────────┘ │
└─────────────────────────────────────────────────────────┘
↓ ↑
┌─────────────────────────────────────────────────────────┐
│ 工具层 (Utils) │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ Logger │ │ Error │ │Validation│ │
│ │ │ │ Handler │ │ │ │
│ └──────────┘ └──────────┘ └──────────┘ │
└─────────────────────────────────────────────────────────┘
↓ ↑
┌─────────────────────────────────────────────────────────┐
│ 数据持久化层 (Storage) │
│ ┌──────────┐ ┌──────────┐ │
│ │localStorage│ │IndexedDB │ (未来) │
│ └──────────┘ └──────────┘ │
└─────────────────────────────────────────────────────────┘
↓ ↑
┌─────────────────────────────────────────────────────────┐
│ 后端服务 (Node.js) │
│ ┌──────────┐ ┌──────────┐ │
│ │LLMService│ │MCPManager│ │
│ └──────────┘ └──────────┘ │
└─────────────────────────────────────────────────────────┘
↓ ↑
┌─────────────────────────────────────────────────────────┐
│ 外部服务 (External APIs) │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │阿里通义 │ │ 火山方舟 │ │MCP Servers│ │
│ └──────────┘ └──────────┘ └──────────┘ │
└─────────────────────────────────────────────────────────┘
发送消息流程
用户输入消息
↓
ChatLayout 组件触发事件
↓
chatStore.sendMessage()
↓
ChatOrchestrator.sendMessageStream()
↓
1. MessageService 创建用户消息
2. 更新话题信息
3. 持久化到 localStorage
↓
4. MessageService 创建助手消息占位符
↓
5. StreamProcessor.processStream()
├─ 准备工具列表(如有 MCP)
├─ 准备上下文消息(限制 20 条)
├─ 选择服务和模型
└─ 执行流式请求
↓
6. 流式响应 onChunk 回调
└─ MessageService.appendMessageContent()
└─ 触发 UI 更新
↓
7. 检查是否有工具调用
└─ 是: ToolExecutor.executeToolCalls()
├─ 执行每个工具
├─ 收集工具结果
└─ 发送结果给 AI(递归)
└─ 否: 完成
↓
8. 更新消息状态为 'success'
9. 更新话题最后消息
10. 持久化
↓
UI 展示最终消息
核心服务
1. ChatOrchestrator(聊天协调器)
职责:
- 统一对外接口
- 协调各服务完成业务流程
- 管理话题和对话
- 处理持久化
核心方法:
class ChatOrchestrator {
// 话题管理
createTopic(name: string, options?: CreateTopicOptions): Topic
getTopics(filter?: TopicFilter): Topic[]
updateTopic(topicId: string, updates: Partial<Topic>): boolean
deleteTopic(topicId: string): boolean
// 消息管理
getMessages(topicId: string): Message[]
deleteMessage(topicId: string, messageId: string): boolean
// 发送消息
sendMessageStream(
options: SendMessageOptions,
onChunk: (event: StreamEvent) => void,
mcpServerId?: string,
signal?: AbortSignal
): Promise<void>
// 重新生成
regenerateMessage(topicId: string, messageId: string): Promise<Message>
// 持久化
private saveTopics(): void
private loadTopics(): void
private saveConversations(): void
private loadConversations(): void
}
2. MessageService(消息服务)
职责:
- 消息 CRUD
- 消息状态管理
- 消息查询和过滤
核心方法:
class MessageService {
createMessage(conversationId: string, options: CreateMessageOptions): Message
getMessages(conversationId: string): Message[]
getMessagesByTopicId(topicId: string): Message[]
updateMessage(conversationId: string, messageId: string, options: UpdateMessageOptions): boolean
updateMessageStatus(conversationId: string, messageId: string, status: MessageStatus): boolean
appendMessageContent(conversationId: string, messageId: string, content: string): boolean
deleteMessage(conversationId: string, messageId: string): boolean
deleteMessagesAfter(conversationId: string, messageId: string): boolean
getSuccessMessages(conversationId: string): Message[]
getRecentSuccessMessages(conversationId: string, limit: number): Message[]
}
3. ConversationService(对话服务)
职责:
- 对话创建、读取、删除
- 对话元数据管理
- 对话与话题的关联
核心方法:
class ConversationService {
createConversation(options: CreateConversationOptions): Conversation
getConversation(conversationId: string): Conversation | undefined
getConversationByTopicId(topicId: string): Conversation | undefined
deleteConversation(conversationId: string): boolean
deleteConversationByTopicId(topicId: string): boolean
updateMetadata(conversationId: string, metadata: Partial<Conversation['metadata']>): boolean
clearMessages(conversationId: string): boolean
}
4. StreamProcessor(流式处理器)
职责:
- 处理流式响应
- 性能监控
- 批量输出
- 工具集成
核心方法:
class StreamProcessor {
async processStream(options: StreamOptions): Promise<StreamResult>
private prepareTools(mcpServerId?: string): Promise<{ tools: any[], mcpServerName: string }>
private prepareMessages(conversation: Conversation, tools: any[], mcpServerName: string): any[]
private selectServiceAndModel(requestedModel?: string): { service: any, selectedModel: string }
private executeStream(...): Promise<StreamResult>
}
特性:
- 上下文限制:最近 20 条消息
- 批量输出:每 3 个字符一次(增强流式效果)
- 性能监控:首字延迟、总耗时、chunk 数
- 工具集成:自动注入系统提示词
5. ToolExecutor(工具执行器)
职责:
- 解析工具调用请求
- 执行 MCP 工具
- 处理工具结果
- 支持递归工具链
核心方法:
class ToolExecutor {
async executeToolCalls(options: ToolCallOptions): Promise<void>
private executeTools(toolCalls: any[], mcpServerId: string, onChunk: Function): Promise<ToolCallResult[]>
private executeSingleTool(toolCall: any, mcpServerId: string, onChunk: Function): Promise<ToolCallResult>
private sendToolResultsToAI(...): Promise<void>
private buildMessagesWithToolResults(...): any[]
}