# MCP 实现全面分析报告

## 问题理解

用户指出：**MCP 应该是动态注册的，不应该在 prompt 中静态配置，否则就失去了 MCP 的意义**。

这个观点完全正确。让我全面分析当前的实现。

## 当前实现分析

### 1. MCP 工具动态注册流程 ✅

**流程**：
```
1. CliApp.init()
   └─> MCPConfigManager()  // 从配置文件加载 MCP 服务器配置
   └─> mcpManager.loadMCPServers()  // 动态加载所有 MCP 服务器
       └─> 对每个服务器调用 loadMCPServer()
           └─> 创建 MCPClient (StdioMCPClient 或 SseMCPClient)
           └─> 获取 client.tools (MCP 服务器提供的工具列表)
           └─> 用 MCPToolWrapper 包装每个工具
           └─> 返回 Tool[]
   └─> agent.toolManager.addTools(mcpTools)  // 动态添加到 Agent
```

**代码位置**：
- `src/app/cli_app.cj:90-97` - MCP 服务器加载
- `src/core/mcp/mcp_config_manager.cj:92-111` - 加载逻辑
- `src/core/mcp/mcp_config_manager.cj:113-147` - 单个服务器加载
- `src/core/mcp/wrapper.cj` - 工具包装器

### 2. 工具描述传递机制

**MCPToolWrapper 实现**：
```cangjie
protected class MCPToolWrapper <: Tool {
    private let serverName: String
    private let mcpTool: Tool
    
    public prop description: String {
        get() { this.mcpTool.description }  // 直接传递原始描述
    }
}
```

**问题**：
- ✅ 工具确实动态注册了
- ❌ 但工具描述是 MCP 服务器提供的原始描述
- ❌ 描述中可能没有明确说明这是 MCP 工具
- ❌ 描述可能不够清晰，LLM 无法正确理解何时使用

### 3. LLM 如何获取工具信息

**CangjieMagic 框架机制**：
- LLM 通过 Function Calling 机制获取工具列表
- 工具的描述（`description`）会被包含在 Function Calling 的 schema 中
- LLM 根据工具名称和描述决定使用哪个工具

**问题**：
- 如果工具描述不够清晰，LLM 可能无法正确选择
- 如果工具名称不够直观，LLM 可能无法关联用户意图

## 根本问题分析

### 问题 1: 工具描述不够清晰

**当前 agentmem 工具描述**：
```
"在 AgentMem 系统中搜索相关记忆"
```

**问题**：
- 没有明确说明这是 MCP 工具
- 没有说明何时使用（用户说"通过agentmem搜索"时应该使用）
- 没有包含关键词"agentmem"或"记忆搜索"

### 问题 2: 工具名称可能不够直观

**当前工具名称**：
- `agentmem_search_memories` - 虽然包含 "agentmem"，但 LLM 可能没有正确关联

### 问题 3: 缺少上下文信息

**MCPToolWrapper 当前实现**：
- 只传递了原始的工具描述
- 没有添加服务器名称、MCP 标识等上下文信息

## 解决方案

### 方案 1: 增强工具描述（推荐）✅

在 `MCPToolWrapper` 中增强工具描述，添加 MCP 上下文信息：

```cangjie
public prop description: String {
    get() {
        // 增强描述，添加 MCP 服务器上下文
        let baseDesc = this.mcpTool.description
        return "[MCP: ${this.serverName}] ${baseDesc}. " +
               "Use this tool when the user mentions '${this.serverName}' or related keywords."
    }
}
```

**优点**：
- 保持动态注册机制
- 不修改 prompt
- 工具描述自动包含 MCP 上下文
- LLM 能够更好地理解何时使用

### 方案 2: 改进工具名称映射

在工具描述中添加别名或关键词：

```cangjie
public prop description: String {
    get() {
        let baseDesc = this.mcpTool.description
        // 为 agentmem 工具添加特殊处理
        if (this.serverName == "agentmem" && this.mcpTool.name.contains("search")) {
            return "${baseDesc}. " +
                   "Keywords: agentmem, 记忆搜索, memory search. " +
                   "When user says '通过agentmem搜索' or 'use agentmem to search', use this tool."
        }
        return "[MCP: ${this.serverName}] ${baseDesc}"
    }
}
```

### 方案 3: 在 extra 字段中添加元数据

利用 Tool 的 `extra` 字段添加元数据：

```cangjie
public prop extra: HashMap<String, String> {
    get() {
        let baseExtra = this.mcpTool.extra
        baseExtra["mcp_server"] = this.serverName
        baseExtra["mcp_tool_name"] = this.mcpTool.name
        if (this.serverName == "agentmem") {
            baseExtra["keywords"] = "agentmem,记忆,memory"
        }
        return baseExtra
    }
}
```

## 推荐实现

**综合方案**：结合方案 1 和方案 2，在 `MCPToolWrapper` 中增强描述：

```cangjie
protected class MCPToolWrapper <: Tool {
    // ... existing code ...
    
    public prop description: String {
        get() {
            let baseDesc = this.mcpTool.description
            
            // 为特定服务器添加增强描述
            match (this.serverName) {
                case "agentmem" =>
                    if (this.mcpTool.name.contains("search")) {
                        return "[MCP: AgentMem] ${baseDesc}. " +
                               "Use this tool when user mentions 'agentmem', '通过agentmem搜索', " +
                               "'记忆搜索', or 'memory search'. " +
                               "This searches memories in the AgentMem system, not files."
                    }
                    return "[MCP: AgentMem] ${baseDesc}"
                case _ =>
                    return "[MCP: ${this.serverName}] ${baseDesc}"
            }
        }
    }
}
```

## 验证步骤

1. **实现增强描述**
2. **重新编译并测试**
3. **验证 LLM 能否正确选择工具**

## 总结

**用户观点完全正确**：
- ✅ MCP 工具应该动态注册
- ✅ 不应该在 prompt 中静态配置
- ✅ 应该通过工具描述让 LLM 自动理解

**问题根源**：
- 工具描述不够清晰，缺少 MCP 上下文
- LLM 无法正确关联用户意图和工具

**解决方案**：
- 在 `MCPToolWrapper` 中增强工具描述
- 添加 MCP 服务器上下文和关键词
- 保持动态注册机制不变

