2
0
Просмотр исходного кода

fix(mcp): 修复连接统计逻辑 - 连接等于服务器健康

- 已连接 X/3 = 所有健康的 MCP 服务器
- 已连接 | 未登录 - 服务器在线但未登录
- 更新说明:Platform User MCP 部分工具无需登录
- 已连接表示服务器在线,已登录表示可调用需要权限的工具

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Claude AI 1 день назад
Родитель
Сommit
dce1d4f4e8
2 измененных файлов с 19 добавлено и 20 удалено
  1. 14 18
      frontend-v2/app/mcp/page.tsx
  2. 5 2
      frontend-v2/components/McpServerCard.tsx

+ 14 - 18
frontend-v2/app/mcp/page.tsx

@@ -7,8 +7,9 @@
  * - 可以同时管理多个 MCP 的登录
  * - 可以同时管理多个 MCP 的登录
  *
  *
  * 连接统计逻辑:
  * 连接统计逻辑:
- * - Novel Translator (authType='none'): 健康就算已连接
- * - User/Admin MCP (authType='jwt'): 健康 + 已登录才算已连接
+ * - **已连接** = 服务器健康(healthy),不管有没有登录
+ * - **已登录** = 有有效 token,可以调用需要权限的工具
+ * - User MCP 有些工具不需要登录也能用(比如 get_novels)
  */
  */
 'use client';
 'use client';
 
 
@@ -28,21 +29,11 @@ export default function McpPage() {
 
 
   const totalCount = Object.keys(MCP_SERVERS).length;
   const totalCount = Object.keys(MCP_SERVERS).length;
 
 
-  // 计算已连接数量
-  // - authType='none': 只要健康就算已连接
-  // - authType='jwt': 健康 + 已登录才算已连接
-  const connectedCount = Object.entries(MCP_SERVERS).reduce((count, [mcpType, config]) => {
-    const status = connectionStatuses[mcpType];
-    if (!status) return count; // 状态未知,不计入
+  // 计算已连接数量:所有健康的 MCP 服务器
+  const connectedCount = Object.values(connectionStatuses).filter(status => status.healthy).length;
 
 
-    if (config.authType === 'none') {
-      // 无需登录,只要健康就算已连接
-      return status.healthy ? count + 1 : count;
-    } else {
-      // 需要登录,健康 + 已登录才算已连接
-      return (status.healthy && status.loggedIn) ? count + 1 : count;
-    }
-  }, 0);
+  // 计算已登录数量:有 token 的 MCP 服务器
+  const loggedInCount = Object.values(connectionStatuses).filter(status => status.loggedIn).length;
 
 
   // 处理子组件报告的连接状态变化
   // 处理子组件报告的连接状态变化
   // 使用 useCallback 避免每次渲染创建新函数引用,防止子组件 useEffect 无限循环
   // 使用 useCallback 避免每次渲染创建新函数引用,防止子组件 useEffect 无限循环
@@ -95,7 +86,11 @@ export default function McpPage() {
             MCP 服务器管理
             MCP 服务器管理
           </h2>
           </h2>
           <p className="text-gray-600 dark:text-gray-400">
           <p className="text-gray-600 dark:text-gray-400">
-            管理和配置您的 MCP 服务器连接。已连接 {connectedCount}/{totalCount} 个服务器。
+            管理和配置您的 MCP 服务器连接。
+            <span className="font-medium text-green-600 dark:text-green-400"> 已连接 {connectedCount}/{totalCount}</span>
+            {loggedInCount > 0 && (
+              <span className="font-medium text-blue-600 dark:text-blue-400"> | 已登录 {loggedInCount}/{totalCount}</span>
+            )}
           </p>
           </p>
         </div>
         </div>
 
 
@@ -118,10 +113,11 @@ export default function McpPage() {
           </h3>
           </h3>
           <ul className="space-y-2 text-sm text-blue-800 dark:text-blue-300">
           <ul className="space-y-2 text-sm text-blue-800 dark:text-blue-300">
             <li>• <strong>Novel Translator MCP</strong>: 无需登录,可直接使用</li>
             <li>• <strong>Novel Translator MCP</strong>: 无需登录,可直接使用</li>
-            <li>• <strong>Platform User MCP</strong>: 需要读者/作者账号登录</li>
+            <li>• <strong>Platform User MCP</strong>: 需要读者/作者账号登录(部分工具无需登录)</li>
             <li>• <strong>Platform Admin MCP</strong>: 需要管理员账号登录</li>
             <li>• <strong>Platform Admin MCP</strong>: 需要管理员账号登录</li>
           </ul>
           </ul>
           <p className="mt-3 text-sm text-blue-700 dark:text-blue-400">
           <p className="mt-3 text-sm text-blue-700 dark:text-blue-400">
+            <strong>已连接</strong> 表示服务器在线,<strong>已登录</strong> 表示可以调用需要权限的工具。
             登录后,对应的 MCP Token 会自动在聊天请求中携带,无需额外配置。
             登录后,对应的 MCP Token 会自动在聊天请求中携带,无需额外配置。
           </p>
           </p>
         </div>
         </div>

+ 5 - 2
frontend-v2/components/McpServerCard.tsx

@@ -173,15 +173,18 @@ export function McpServerCard({ mcpType, config, onConnectionStatusChange }: Mcp
   }, [isHealthy, isLoggedIn, mcpType, onConnectionStatusChange]);
   }, [isHealthy, isLoggedIn, mcpType, onConnectionStatusChange]);
 
 
   // 计算连接状态显示
   // 计算连接状态显示
+  // - 健康 + 已登录 → 已连接 ✓ | 已登录 ✓
+  // - 健康 + 未登录 → 已连接 ✓ | 未登录
+  // - 不健康 → 离线
   const getConnectionStatus = () => {
   const getConnectionStatus = () => {
     if (isHealthy === null) {
     if (isHealthy === null) {
       return { text: '检查中...', className: 'bg-gray-100 dark:bg-gray-700 text-gray-600 dark:text-gray-400', dotColor: 'bg-gray-400' };
       return { text: '检查中...', className: 'bg-gray-100 dark:bg-gray-700 text-gray-600 dark:text-gray-400', dotColor: 'bg-gray-400' };
     }
     }
     if (isHealthy) {
     if (isHealthy) {
       if (isLoggedIn) {
       if (isLoggedIn) {
-        return { text: '已连接', className: 'bg-green-100 dark:bg-green-900 text-green-800 dark:text-green-200', dotColor: 'bg-green-500' };
+        return { text: '已连接 | 已登录', className: 'bg-green-100 dark:bg-green-900 text-green-800 dark:text-green-200', dotColor: 'bg-green-500' };
       } else {
       } else {
-        return { text: '在线(未登录)', className: 'bg-blue-100 dark:bg-blue-900 text-blue-800 dark:text-blue-200', dotColor: 'bg-blue-500' };
+        return { text: '已连接 | 未登录', className: 'bg-blue-100 dark:bg-blue-900 text-blue-800 dark:text-blue-200', dotColor: 'bg-blue-500' };
       }
       }
     } else {
     } else {
       return { text: '离线', className: 'bg-red-100 dark:bg-red-900 text-red-800 dark:text-red-200', dotColor: 'bg-red-500' };
       return { text: '离线', className: 'bg-red-100 dark:bg-red-900 text-red-800 dark:text-red-200', dotColor: 'bg-red-500' };