这是一个简单的天气工具,演示了使用模型上下文协议(MCP)进行客户端-服务器交互。仅用于演示目的。
用户:"东京的天气怎么样?"
响应:"东京的天气是晴朗的。"
这是Kotlin版本的mcp-minimal-client-weather-server-sample
客户端:src/main/kotlin/Client.kt
服务器:server.main.kts
图1:初始化与工具发现
sequenceDiagram
autonumber
participant 用户
participant 客户端应用 as 客户端应用(主机)<br>在本地PC上
participant 大型语言模型 as 大型语言模型(例如Claude)<br>远程服务
participant MCP客户端 as MCP客户端(内部组件)<br>在本地PC上的客户端应用中
participant MCP服务器 as MCP服务器(例如工具服务器)<br>在本地PC上
Note over 用户, MCP服务器: 用户启动客户端应用,开始连接到MCP服务器
客户端应用->>+MCP客户端: 指令准备连接到特定的MCP服务器
Note right of 客户端应用: 主机管理每个服务器的MCP客户端实例
MCP客户端->>+MCP服务器: 1. 初始化(请求)<br>[协议版本, 客户端能力]
Note over MCP客户端, MCP服务器: 开始建立连接和能力交换(JSON-RPC)
MCP服务器-->>-MCP客户端: 2. 初始化(响应)<br>[选定的协议版本, 服务器能力(工具、资源等)]
Note over MCP客户端, MCP服务器: 服务器通知其可用能力
MCP客户端->>MCP服务器: 3. 通知/初始化(初始化完成通知)
Note over MCP客户端, MCP服务器: 握手完成,可以进行正常通信
MCP客户端-->>-客户端应用: 初始化成功及服务器能力通知(通过成功的初始化等待隐式通知)
Note right of 客户端应用: 主机(客户端应用)现在知道服务器已准备好
客户端应用->>MCP客户端: 4. 指令获取服务器提供的工具列表(会话.list_tools())
MCP客户端->>+MCP服务器: 5. 工具/列表(请求)
Note over MCP客户端, MCP服务器: 请求服务器定义的工具列表
MCP服务器-->>-MCP客户端: 6. 工具/列表(响应)<br>[{"name": "get_weather", "description": "...", "inputSchema": {...}}]
Note over MCP客户端, MCP服务器: 示例:返回“get_weather”工具的定义
MCP客户端-->>客户端应用: 7. 通知工具列表(包含“get_weather”等)通过tools_response对象
Note right of 客户端应用: 主机存储/处理检索到的工具信息(格式化工具以供大型语言模型使用)
客户端应用->>大型语言模型: 8. 将可用工具信息发送给大型语言模型<br>(例如,通过系统提示使用格式化的工具提示)
Note over 客户端应用, 大型语言模型: 主机告知大型语言模型“get_weather”可用<br>大型语言模型可以根据此信息决定是否使用该工具
图2:工具执行流程
sequenceDiagram
autonumber
participant 用户
participant 客户端应用 as 客户端应用(主机)<br>在本地PC上
participant 大型语言模型 as 大型语言模型(例如Claude)<br>远程服务
participant MCP客户端 as MCP客户端(内部组件)<br>在本地PC上的客户端应用中
participant MCP服务器 as MCP服务器(例如工具服务器)<br>在本地PC上
用户->>客户端应用: 1. "东京的天气怎么样?"
Note right of 用户: 用户提出可能需要工具的问题
客户端应用->>大型语言模型: 2. 转发用户的带有上下文的问题<br>[系统提示(带工具信息)+ 用户问题]
Note over 客户端应用, 大型语言模型: 主机发送问题和格式化的工具信息(“get_weather”)给大型语言模型
大型语言模型->>客户端应用: 3. 大型语言模型响应,请求使用工具<br>响应:`{"tool_name": "get_weather", "arguments": {"location": "Tokyo"}}`
Note over 客户端应用, 大型语言模型: 根据提供的工具信息,大型语言模型决定使用天气工具<br>并生成所需的JSON结构及其参数
客户端应用->>+客户端应用: (可选) 4. 确认工具执行<br>"在工具服务器上执行'get_weather'?"
用户->>客户端应用: (可选) 5. "是"
Note over 客户端应用, 用户: 为了安全/透明,主机可能会寻求用户许可(示例代码中未实现)
客户端应用->>+MCP客户端: 6. 指令执行“get_weather”工具(会话.call_tool())<br>参数:{"location": "Tokyo"}
Note right of 客户端应用: 主机通过MCP客户端指示MCP服务器
MCP客户端->>+MCP服务器: 7. 工具/调用(请求)<br>[名称: "get_weather", 参数: {"location": "Tokyo"}]
Note over MCP客户端, MCP服务器: 调用服务器函数,指定工具名称和参数(JSON-RPC)
MCP服务器->>MCP服务器: 内部处理(执行get_weather函数)
Note over MCP服务器: 记录执行情况,返回结果(例如,“晴朗”)
MCP服务器-->>-MCP客户端: 8. 工具/调用(响应)<br>[结果: {内容: [{类型: "文本", 文本: "晴朗"}]}]
Note over MCP客户端, MCP服务器: 服务器以结构化格式返回处理结果(天气信息)
MCP客户端-->>-客户端应用: 9. 通知工具执行结果<br>结果对象包含:“晴朗”(从tool_result_obj.content[0].text提取)
客户端应用->>大型语言模型: 11. 将工具执行结果反馈给大型语言模型<br>新用户消息:“工具'get_weather'返回:'晴朗'。根据这个回答原始问题。”
Note over 客户端应用, 大型语言模型: 主机将从服务器获得的信息反馈给大型语言模型
大型语言模型->>客户端应用: 11. 生成最终响应(作为文本)<br>"东京的天气是晴朗的。"
客户端应用->>用户: 12. 显示由大型语言模型生成的最终响应
Note right of 客户端应用: 向用户提供最终答案