Skip to content

2.2 Host、Client、Server详解

🎯 学习目标:深入理解MCP三大核心组件的职责、关系和实现方式
⏱️ 预计时间:45分钟
📊 难度等级:⭐⭐

🎭 三大角色的戏剧比喻

在深入技术细节之前,让我们用一个戏剧比喻来理解MCP的三大核心组件:

🎪 MCP剧场演出
────────────────────────────────
🎭 导演 (Host)     - 总体协调,决定剧情走向
🎤 翻译 (Client)   - 负责演员间的沟通翻译  
🎨 演员 (Server)   - 各自表演专业技能

在这个比喻中:

  • 导演(Host):理解观众需求,指导整场演出
  • 翻译(Client):确保导演和演员能够有效沟通
  • 演员(Server):各有专长,负责具体的表演

🏠 Host(宿主):MCP生态的大脑

🧠 Host的核心职责

Host是MCP生态系统的控制中心,就像一个智能指挥官:

📋 Host的详细职责

职责说明举例
用户交互提供友好的用户界面Web界面、CLI、语音交互
意图理解解析用户需求和意图"发邮件" → 需要邮件工具
任务规划制定执行计划和步骤先查联系人,再发送邮件
工具编排协调多个工具协作组合查询、计算、通知等工具
结果整合整合多个工具的输出合并数据,格式化展示
错误处理处理异常和容错恢复工具失败时的备用方案

💻 Host的技术实现

基础Host架构

javascript
class MCPHost {
    constructor() {
        this.aiModel = new AIModel();
        this.mcpClients = new Map(); // 管理多个MCP客户端
        this.taskPlanner = new TaskPlanner();
        this.resultProcessor = new ResultProcessor();
    }
    
    async processUserRequest(userInput) {
        try {
            // 1. 理解用户意图
            const intent = await this.aiModel.parseIntent(userInput);
            console.log('用户意图:', intent);
            
            // 2. 制定执行计划
            const plan = await this.taskPlanner.createPlan(intent);
            console.log('执行计划:', plan);
            
            // 3. 执行计划中的每个步骤
            const results = [];
            for (const step of plan.steps) {
                const result = await this.executeStep(step);
                results.push(result);
            }
            
            // 4. 整合结果
            const finalResult = await this.resultProcessor.integrate(results);
            
            // 5. 生成用户友好的回复
            return await this.aiModel.generateResponse(finalResult);
            
        } catch (error) {
            return this.handleError(error);
        }
    }
    
    async executeStep(step) {
        const client = this.mcpClients.get(step.serverId);
        if (!client) {
            throw new Error(`找不到服务器: ${step.serverId}`);
        }
        
        return await client.callTool(step.toolName, step.parameters);
    }
}

高级Host功能

javascript
class AdvancedMCPHost extends MCPHost {
    constructor() {
        super();
        this.conversationContext = new ConversationContext();
        this.preferenceManager = new UserPreferenceManager();
        this.securityManager = new SecurityManager();
    }
    
    // 上下文感知的请求处理
    async processWithContext(userInput, conversationId) {
        // 获取对话上下文
        const context = await this.conversationContext.get(conversationId);
        
        // 结合上下文理解意图
        const intent = await this.aiModel.parseIntentWithContext(
            userInput, 
            context
        );
        
        // 个性化任务规划
        const userPrefs = await this.preferenceManager.getPreferences(
            context.userId
        );
        const plan = await this.taskPlanner.createPersonalizedPlan(
            intent, 
            userPrefs
        );
        
        // 安全检查
        await this.securityManager.validatePlan(plan, context.userId);
        
        // 执行并更新上下文
        const result = await this.executePlan(plan);
        await this.conversationContext.update(conversationId, {
            intent,
            plan,
            result
        });
        
        return result;
    }
}

🎯 Host的实际应用

VS Code中的MCP Host

typescript
// VS Code扩展中的MCP Host实现
export class VSCodeMCPHost {
    private clients: Map<string, MCPClient> = new Map();
    private outputChannel: vscode.OutputChannel;
    
    constructor() {
        this.outputChannel = vscode.window.createOutputChannel('MCP Host');
    }
    
    // 处理编辑器命令
    async handleEditorCommand(command: string, editor: vscode.TextEditor) {
        const intent = this.parseEditorIntent(command, editor);
        
        switch (intent.type) {
            case 'code_analysis':
                return await this.analyzeCode(editor);
            case 'code_generation':
                return await this.generateCode(intent.requirements);
            case 'refactor':
                return await this.refactorCode(editor, intent.target);
            default:
                throw new Error(`未知命令: ${command}`);
        }
    }
    
    private async analyzeCode(editor: vscode.TextEditor) {
        const codeAnalysisClient = this.clients.get('code-analysis');
        const result = await codeAnalysisClient.callTool('analyze', {
            code: editor.document.getText(),
            language: editor.document.languageId
        });
        
        // 在VS Code中显示分析结果
        this.showAnalysisResults(result);
        return result;
    }
}

🤖 Client(客户端):MCP协议的执行者

🔗 Client的核心职责

Client是MCP协议的具体实现者,负责与Server的所有通信:

📋 Client的详细功能

功能模块职责技术要点
连接管理建立和维护与Server的连接连接池、重连机制、健康检查
协议处理实现MCP协议规范消息序列化、协议版本协商
能力发现发现和缓存Server能力能力查询、缓存更新、版本管理
消息路由将请求路由到正确的Server负载均衡、故障转移、超时处理
结果处理处理Server响应结果解析、错误处理、数据转换
安全控制认证和权限验证身份认证、访问控制、数据加密

💻 Client的技术实现

基础Client实现

javascript
class MCPClient {
    constructor() {
        this.connections = new Map();
        this.capabilities = new Map();
        this.eventEmitter = new EventEmitter();
    }
    
    // 连接到MCP服务器
    async connect(serverInfo) {
        try {
            // 建立底层连接(WebSocket、HTTP、进程通信等)
            const transport = await this.createTransport(serverInfo);
            
            // 创建MCP连接
            const connection = new MCPConnection(transport);
            
            // 协议握手
            await this.performHandshake(connection, serverInfo);
            
            // 发现服务器能力
            const capabilities = await this.discoverCapabilities(connection);
            
            // 缓存连接和能力
            this.connections.set(serverInfo.id, connection);
            this.capabilities.set(serverInfo.id, capabilities);
            
            // 监听连接事件
            this.setupConnectionListeners(connection, serverInfo.id);
            
            this.eventEmitter.emit('connected', serverInfo.id);
            
            return connection;
            
        } catch (error) {
            console.error(`连接服务器失败: ${serverInfo.id}`, error);
            throw error;
        }
    }
    
    // 调用工具
    async callTool(serverId, toolName, parameters) {
        const connection = this.connections.get(serverId);
        if (!connection) {
            throw new Error(`未连接到服务器: ${serverId}`);
        }
        
        // 验证工具存在
        const capabilities = this.capabilities.get(serverId);
        const tool = capabilities.tools.find(t => t.name === toolName);
        if (!tool) {
            throw new Error(`工具不存在: ${toolName}`);
        }
        
        // 验证参数
        this.validateParameters(parameters, tool.inputSchema);
        
        // 构造MCP消息
        const message = {
            jsonrpc: '2.0',
            id: this.generateRequestId(),
            method: 'tools/call',
            params: {
                name: toolName,
                arguments: parameters
            }
        };
        
        // 发送请求并等待响应
        const response = await connection.request(message);
        
        if (response.error) {
            throw new MCPError(response.error.message, response.error.code);
        }
        
        return response.result;
    }
    
    // 协议握手
    async performHandshake(connection, serverInfo) {
        const handshakeMessage = {
            jsonrpc: '2.0',
            id: 1,
            method: 'initialize',
            params: {
                protocolVersion: '2025-01-07',
                capabilities: {
                    roots: {
                        listChanged: true
                    },
                    sampling: {}
                },
                clientInfo: {
                    name: 'MCP Client',
                    version: '1.0.0'
                }
            }
        };
        
        const response = await connection.request(handshakeMessage);
        
        if (response.error) {
            throw new Error(`握手失败: ${response.error.message}`);
        }
        
        // 发送初始化完成通知
        await connection.notify({
            jsonrpc: '2.0',
            method: 'notifications/initialized'
        });
        
        return response.result;
    }
}

高级Client功能

javascript
class AdvancedMCPClient extends MCPClient {
    constructor() {
        super();
        this.connectionPool = new ConnectionPool();
        this.circuitBreaker = new CircuitBreaker();
        this.metricsCollector = new MetricsCollector();
    }
    
    // 带重试的工具调用
    async callToolWithRetry(serverId, toolName, parameters, options = {}) {
        const maxRetries = options.maxRetries || 3;
        const retryDelay = options.retryDelay || 1000;
        
        for (let attempt = 1; attempt <= maxRetries; attempt++) {
            try {
                // 检查熔断器状态
                if (this.circuitBreaker.isOpen(serverId)) {
                    throw new Error(`服务器 ${serverId} 熔断中`);
                }
                
                const startTime = Date.now();
                const result = await this.callTool(serverId, toolName, parameters);
                
                // 记录成功指标
                this.metricsCollector.recordSuccess(serverId, Date.now() - startTime);
                this.circuitBreaker.recordSuccess(serverId);
                
                return result;
                
            } catch (error) {
                console.warn(`工具调用失败 (尝试 ${attempt}/${maxRetries}):`, error);
                
                // 记录失败指标
                this.metricsCollector.recordFailure(serverId, error);
                this.circuitBreaker.recordFailure(serverId);
                
                if (attempt === maxRetries) {
                    throw error;
                }
                
                // 等待重试
                await this.sleep(retryDelay * attempt);
            }
        }
    }
    
    // 批量工具调用
    async callToolsBatch(requests) {
        const promises = requests.map(async (request) => {
            try {
                const result = await this.callTool(
                    request.serverId,
                    request.toolName,
                    request.parameters
                );
                return { success: true, result, request };
            } catch (error) {
                return { success: false, error, request };
            }
        });
        
        return await Promise.all(promises);
    }
}

🏪 Server(服务器):MCP工具的提供者

🛠️ Server的核心职责

Server是MCP生态中的工具提供者,每个Server专注于特定领域的功能:

📋 Server的功能模块

模块职责实现要点
工具管理注册和管理提供的工具工具注册、元数据管理、版本控制
资源管理管理可访问的资源资源抽象、访问控制、生命周期管理
协议实现实现MCP服务器端协议消息处理、错误响应、状态管理
执行引擎执行具体的工具逻辑参数验证、业务逻辑、结果封装
安全机制认证授权和安全控制身份验证、权限检查、数据保护

💻 Server的技术实现

基础Server框架

javascript
class MCPServer {
    constructor(name) {
        this.name = name;
        this.tools = new Map();
        this.resources = new Map();
        this.prompts = new Map();
        this.requestHandlers = new Map();
        
        // 注册核心处理器
        this.setupCoreHandlers();
    }
    
    // 注册工具
    registerTool(name, handler, schema) {
        this.tools.set(name, {
            name,
            description: schema.description,
            inputSchema: schema.inputSchema,
            handler: this.wrapToolHandler(handler)
        });
        
        console.log(`工具已注册: ${name}`);
    }
    
    // 包装工具处理器,添加验证和错误处理
    wrapToolHandler(handler) {
        return async (parameters) => {
            try {
                // 执行工具逻辑
                const result = await handler(parameters);
                
                // 标准化返回格式
                return {
                    content: [
                        {
                            type: 'text',
                            text: typeof result === 'string' ? result : JSON.stringify(result)
                        }
                    ]
                };
            } catch (error) {
                console.error('工具执行错误:', error);
                throw new MCPError(
                    `工具执行失败: ${error.message}`,
                    'TOOL_EXECUTION_ERROR'
                );
            }
        };
    }
    
    // 处理MCP请求
    async handleRequest(request) {
        const { method, params, id } = request;
        
        try {
            const handler = this.requestHandlers.get(method);
            if (!handler) {
                throw new MCPError(
                    `不支持的方法: ${method}`,
                    'METHOD_NOT_FOUND'
                );
            }
            
            const result = await handler(params);
            
            return {
                jsonrpc: '2.0',
                id,
                result
            };
            
        } catch (error) {
            return {
                jsonrpc: '2.0',
                id,
                error: {
                    code: error.code || 'INTERNAL_ERROR',
                    message: error.message
                }
            };
        }
    }
    
    // 设置核心处理器
    setupCoreHandlers() {
        // 初始化处理器
        this.requestHandlers.set('initialize', async (params) => {
            return {
                protocolVersion: '2025-01-07',
                capabilities: {
                    tools: {
                        listChanged: true
                    },
                    resources: {
                        subscribe: true,
                        listChanged: true
                    }
                },
                serverInfo: {
                    name: this.name,
                    version: '1.0.0'
                }
            };
        });
        
        // 工具列表处理器
        this.requestHandlers.set('tools/list', async () => {
            return {
                tools: Array.from(this.tools.values()).map(tool => ({
                    name: tool.name,
                    description: tool.description,
                    inputSchema: tool.inputSchema
                }))
            };
        });
        
        // 工具调用处理器
        this.requestHandlers.set('tools/call', async (params) => {
            const { name, arguments: args } = params;
            const tool = this.tools.get(name);
            
            if (!tool) {
                throw new MCPError(`工具不存在: ${name}`, 'TOOL_NOT_FOUND');
            }
            
            return await tool.handler(args);
        });
    }
}

专业化Server示例

javascript
// 数学计算Server
class MathCalculatorServer extends MCPServer {
    constructor() {
        super('math-calculator');
        this.registerMathTools();
    }
    
    registerMathTools() {
        // 基础计算工具
        this.registerTool('add', 
            (params) => params.a + params.b,
            {
                description: '两数相加',
                inputSchema: {
                    type: 'object',
                    properties: {
                        a: { type: 'number', description: '第一个数' },
                        b: { type: 'number', description: '第二个数' }
                    },
                    required: ['a', 'b']
                }
            }
        );
        
        // 高级计算工具
        this.registerTool('solve_equation',
            async (params) => {
                const { equation, variable } = params;
                // 这里可以集成数学求解库
                return `方程 ${equation} 关于 ${variable} 的解`;
            },
            {
                description: '求解数学方程',
                inputSchema: {
                    type: 'object',
                    properties: {
                        equation: { type: 'string', description: '数学方程' },
                        variable: { type: 'string', description: '未知变量' }
                    },
                    required: ['equation', 'variable']
                }
            }
        );
        
        // 统计分析工具
        this.registerTool('statistics',
            (params) => {
                const { numbers } = params;
                const sum = numbers.reduce((a, b) => a + b, 0);
                const mean = sum / numbers.length;
                const variance = numbers.reduce((acc, num) => acc + Math.pow(num - mean, 2), 0) / numbers.length;
                
                return {
                    count: numbers.length,
                    sum,
                    mean,
                    variance,
                    stddev: Math.sqrt(variance)
                };
            },
            {
                description: '数组统计分析',
                inputSchema: {
                    type: 'object',
                    properties: {
                        numbers: {
                            type: 'array',
                            items: { type: 'number' },
                            description: '数字数组'
                        }
                    },
                    required: ['numbers']
                }
            }
        );
    }
}

🔄 三者协作的完整流程

📊 详细的交互时序图

🎯 协作关系总结

组件主要职责与其他组件的关系
Host用户交互、任务编排通过Client调用Server,向用户展示结果
Client协议实现、连接管理接收Host指令,与Server通信
Server工具实现、资源提供响应Client请求,执行具体功能

🎯 本节小结

通过这一小节,你应该已经深入理解了:

Host的职责:用户交互、意图理解、任务规划、工具编排、结果整合
Client的职责:连接管理、协议处理、能力发现、消息路由、结果处理
Server的职责:工具注册、资源管理、协议实现、执行引擎、安全控制
协作关系:三者如何配合完成完整的AI工具调用流程
技术实现:每个组件的核心代码结构和实现要点

🤔 深入思考

  1. 💭 在你的项目中,你会如何设计Host的用户交互界面?
  2. 🔍 Client的连接管理需要考虑哪些异常情况?
  3. 🛠️ 你想开发什么类型的MCP Server?

理解了三大组件的职责,是不是想知道它们之间具体是如何通信的?

👉 下一小节:2.3 通信协议