内容
# MCP(模型上下文协议)最小Kotlin客户端服务器示例
一个简单的天气工具,演示了使用模型上下文协议(Model Context Protocol,MCP)的服务器与客户端之间的交互。仅用于演示目的。
用户:“东京的天气怎么样?”
响应:“东京的天气是晴天。”
这是 [mcp-minimal-client-weather-server-sample](https://github.com/takahirom/mcp-minimal-client-weather-server-sample) 的Kotlin版本。
客户端:src/main/kotlin/Client.kt
服务器:server.main.kts
**图1:初始化和工具发现**
```mermaid
sequenceDiagram
autonumber
participant User
participant ClientApp as ClientApp (Host)<br>on Local PC
participant LLM as LLM (e.g., Claude)<br>Remote Service
participant MCPClient as MCPClient (Internal Component)<br>in ClientApp on Local PC
participant MCPServer as MCPServer (e.g., Tool Server)<br>on Local PC
Note over User, MCPServer: 用户启动ClientApp,开始连接到MCPServer
ClientApp->>+MCPClient: 指示准备连接到特定的MCPServer
Note right of ClientApp: 主机管理每个服务器的MCPClient实例
MCPClient->>+MCPServer: 1. initialize (请求)<br>[protocol_version, client_capabilities]
Note over MCPClient, MCPServer: 开始建立连接并交换能力(JSON-RPC)
MCPServer-->>-MCPClient: 2. initialize (响应)<br>[selected_protocol_version, server_capabilities (tools, resources, etc.)]
Note over MCPClient, MCPServer: 服务器通知其可用的能力
MCPClient->>MCPServer: 3. notifications/initialized (初始化完成通知)
Note over MCPClient, MCPServer: 握手完成,正常通信可行
MCPClient-->>-ClientApp: 初始化成功 & 服务器能力通知(通过成功的初始化等待隐式通知)
Note right of ClientApp: 主机(ClientApp)现在知道服务器已准备好
ClientApp->>MCPClient: 4. 指示获取服务器提供的工具列表 (session.list_tools())
MCPClient->>+MCPServer: 5. tools/list (请求)
Note over MCPClient, MCPServer: 请求服务器上定义的工具列表
MCPServer-->>-MCPClient: 6. tools/list (响应)<br>[{"name": "get_weather", "description": "...", "inputSchema": {...}}]
Note over MCPClient, MCPServer: 示例:返回'get_weather'工具的定义
MCPClient-->>ClientApp: 7. 通知工具列表(包含'get_weather'等)通过tools_response对象
Note right of ClientApp: 主机存储/处理检索到的工具信息 (format_tools_for_llm)
ClientApp->>LLM: 8. 将可用工具信息发送给LLM<br>(例如,通过使用格式化的tools_prompt的系统提示)
Note over ClientApp, LLM: 主机通知LLM 'get_weather' 可用<br>LLM现在可以根据此信息决定是否使用该工具
```
**图2:工具执行流程**
```mermaid
sequenceDiagram
autonumber
participant User
participant ClientApp as ClientApp (Host)<br>on Local PC
participant LLM as LLM (e.g., Claude)<br>Remote Service
participant MCPClient as MCPClient (Internal Component)<br>in ClientApp on Local PC
participant MCPServer as MCPServer (e.g., Tool Server)<br>on Local PC
User->>ClientApp: 1. “东京的天气怎么样?”
Note right of User: 用户提出一个可能需要工具的问题
ClientApp->>LLM: 2. 转发用户的问题和上下文<br>[系统提示(带工具信息) + 用户问题]
Note over ClientApp, LLM: 主机将问题和格式化的工具信息('get_weather')发送给LLM
LLM->>ClientApp: 3. LLM响应,请求使用工具<br>响应: `{"tool_name": "get_weather", "arguments": {"location": "Tokyo"}}`
Note over ClientApp, LLM: 基于提供的工具信息,LLM决定使用天气工具<br>并生成所需的JSON结构及参数
ClientApp->>User: (可选) 4. 确认工具执行<br>“在工具服务器上执行'get_weather'吗?”
User->>ClientApp: (可选) 5. “是的”
Note over ClientApp, User: 出于安全性/透明性,主机可能会寻求用户许可(在示例代码中未实现)
ClientApp->>+MCPClient: 6. 指示执行'get_weather'工具 (session.call_tool())<br>参数: {"location": "Tokyo"}
Note right of ClientApp: 主机通过MCPClient指示MCP服务器
MCPClient->>+MCPServer: 7. tools/call (请求)<br>[name: "get_weather", arguments: {"location": "Tokyo"}]
Note over MCPClient, MCPServer: 使用指定的工具名称和参数调用服务器函数(JSON-RPC)
MCPServer->>MCPServer: 内部处理(执行get_weather函数)
Note over MCPServer: 记录执行,返回结果(例如,“晴天”)
MCPServer-->>-MCPClient: 8. tools/call (响应)<br>[result: {content: [{type: "text", text: "Sunny"}]}]
Note over MCPClient, MCPServer: 服务器以结构化格式返回处理结果(天气信息)
MCPClient-->>-ClientApp: 9. 通知工具执行结果<br>结果对象包含:“Sunny”(提取自tool_result_obj.content[0].text)
ClientApp->>LLM: 10. 将工具执行结果发送回LLM<br>新用户消息:“工具'get_weather'返回:'Sunny'。根据此回答原始问题。”
Note over ClientApp, LLM: 主机将从服务器获得的信息反馈给LLM
LLM->>ClientApp: 11. 生成最终响应(作为文本)<br>“东京的天气是晴天。”
ClientApp->>User: 12. 显示LLM生成的最终响应
Note right of ClientApp: 向用户呈现最终答案
```