已经有很多的文章介绍MCP server,MCP Client工作原理,这里不做太多介绍。但是很多介绍都只是侧重介绍概念,实际的工作原理理解起来对初学者还是不太友好。本文以一个智能旅游咨询系统为例,详细说明在利用 Model Context Protocol(MCP)应用时,从用户输入到给出最终结果,上下文信息的传递过程以及每一步的封装填充情况。能够让读者快速了解,所谓的model context protocol中上下文的含义,同一般的function call的差异。
工作过程与原理介绍
场景设定
用户希望了解北京故宫的开放时间和门票价格,系统利用 MCP 协调不同的工具(如开放时间查询工具、门票价格查询工具)来获取相关信息并给出回答。
整个系统的消息交互图如下:
完整流程概述
- 客户端与MCP服务器建立连接,获取可用工具列表
- 用户输入问题,客户端封装请求
- 客户端调用LLM进行意图分析,生成工具调用指令
- 客户端向MCP服务器发起工具调用(需用户确认)
- MCP服务器执行工具并返回结果
- 客户端整合结果,调用LLM生成最终回答
- 客户端向用户展示最终结果
详细步骤说明
1. 客户端初始化 & 获取工具列表
客户端首次连接MCP服务器时,通过/tools
端点获取注册的工具列表:
请求:
GET /tools HTTP/1.1
Host: mcp-server.example.com
Accept: application/json
响应:
{"tools": [{"name": "opening_hours_query","description": "景区开放时间查询工具","parameters": {"location": "string"}},{"name": "ticket_price_query","description": "景区门票价格查询工具","parameters": {"location": "string"}}]
}
说明:客户端需要缓存工具列表,用于后续LLM分析。
2. 用户输入 & 请求封装
用户在客户端界面输入问题:
“北京故宫的开放时间和门票价格是多少?”
客户端封装请求,包含用户问题、用户标识和时间戳:
{"user_id": "12345","timestamp": "2025-04-09 12:00:00","question": "北京故宫的开放时间和门票价格是多少?"
}
3. LLM分析 & 生成工具调用指令
客户端将用户问题+工具描述发送给LLM:
{"question": "北京故宫的开放时间和门票价格是多少?","available_tools": [{"name": "opening_hours_query","description": "景区开放时间查询工具"},{"name": "ticket_price_query","description": "景区门票价格查询工具"}]
}
LLM返回结构化工具调用指令:
{"request_id": "abcdef123456","llm_response": [{ "tool_call_id": "call_1","tool_name": "opening_hours_query","parameters": {"location": "北京故宫"}},{ "tool_call_id": "call_2","tool_name": "ticket_price_query","parameters": {"location": "北京故宫"}}]
}
4. 客户端发起工具调用(含用户确认)
客户端按照MCP协议(JSON-RPC)格式封装请求,并先向用户展示确认对话框:
用户确认界面:
即将执行以下操作:
1. 查询[北京故宫]的开放时间
2. 查询[北京故宫]的门票价格是否继续? [确认] [取消]
用户确认后,发送正式请求:
{"jsonrpc": "2.0","method": "tool/execute","params": {"tool": "opening_hours_query","arguments": {"location": "北京故宫"}},"id": "call_1"
}
5. MCP服务器执行工具
MCP服务器执行工具并返回结果:
{"jsonrpc": "2.0","result": {"status": "success","data": "旺季8:30-17:00,淡季8:30-16:30"},"id": "call_1"
}
6. 客户端整合结果 & 生成最终回答
客户端收集所有工具结果后,再次调用LLM:
{"request_id": "abcdef123456","question": "北京故宫的开放时间和门票价格是多少?","tool_results": [{"tool_call_id": "call_1","tool_name": "opening_hours_query","result": "旺季8:30-17:00,淡季8:30-16:30"},{"tool_call_id": "call_2","tool_name": "ticket_price_query","result": "旺季60元,淡季40元"}]
}
LLM生成自然语言回答:
{"final_answer": "北京故宫开放时间:旺季8:30-17:00,淡季8:30-16:30;门票价格:旺季60元,淡季40元。"
}
7. 客户端展示最终结果
将LLM生成的回答呈现给用户:
“北京故宫开放时间:旺季8:30-17:00,淡季8:30-16:30;门票价格:旺季60元,淡季40元。”
这个流程确保了系统的安全性、可扩展性和协议合规性。