客戶端開發
在本教程中,你將學習如何構建一個連接到 MCP 服務器的 LLM 驅動的聊天機器人客戶端。建議先完成服務器快速入門教程,瞭解構建第一個服務器的基礎知識。
系統要求
開始之前,請確保你的系統滿足以下要求:
- Mac 或 Windows 電腦
- 已安裝最新版本的 Python
- 已安裝最新版本的
uv
配置環境
首先,使用 uv 創建一個新的 Python 項目:
# 創建項目目錄
uv init mcp-client
cd mcp-client
# 創建虛擬環境
uv venv
# 激活虛擬環境
# Windows系統:
.venv\Scripts\activate
# Unix或MacOS系統:
source .venv/bin/activate
# 安裝必需的包
uv add mcp anthropic python-dotenv
# 刪除模板文件
rm hello.py
# 創建主文件
touch client.py設置 API 密鑰
你需要從 Anthropic 控制檯 獲取一個 Anthropic API 密鑰。
創建 .env 文件來存儲密鑰:
# 創建 .env 文件
touch .env將密鑰添加到 .env 文件中:
ANTHROPIC_API_KEY=<你的密鑰>將 .env 添加到 .gitignore:
echo ".env" >> .gitignore創建客戶端
基本客戶端結構
首先,設置導入語句並創建基本的客戶端類。
import asyncio
from typing import Optional
from contextlib import AsyncExitStack
from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client
from anthropic import Anthropic
from dotenv import load_dotenv
load_dotenv() # 從 .env 加載環境變量
class MCPClient:
def __init__(self):
# 初始化會話和客戶端對象
self.session: Optional[ClientSession] = None
self.exit_stack = AsyncExitStack()
self.anthropic = Anthropic()服務器連接管理
接下來,實現連接到 MCP 服務器的方法:
async def connect_to_server(self, server_script_path: str):
"""連接到 MCP 服務器
參數:
server_script_path: 服務器腳本路徑 (.py 或 .js)
"""
is_python = server_script_path.endswith('.py')
is_js = server_script_path.endswith('.js')
if not (is_python or is_js):
raise ValueError("服務器腳本必須是 .py 或 .js 文件")
command = "python" if is_python else "node"
server_params = StdioServerParameters(
command=command,
args=[server_script_path],
env=None
)
stdio_transport = await self.exit_stack.enter_async_context(stdio_client(server_params))
self.stdio, self.write = stdio_transport
self.session = await self.exit_stack.enter_async_context(ClientSession(self.stdio, self.write))
await self.session.initialize()
# 列出可用工具
response = await self.session.list_tools()
tools = response.tools
print("\n已連接到服務器,可用工具:", [tool.name for tool in tools])查詢處理邏輯
現在添加處理查詢和工具調用的核心功能:
async def process_query(self, query: str) -> str:
"""使用 Claude 和可用工具處理查詢"""
messages = [
{
"role": "user",
"content": query
}
]
response = await self.session.list_tools()
available_tools = [{
"name": tool.name,
"description": tool.description,
"input_schema": tool.inputSchema
} for tool in response.tools]
# 初始 Claude API 調用
response = self.anthropic.messages.create(
model="claude-3-5-sonnet-20241022",
max_tokens=1000,
messages=messages,
tools=available_tools
)
# 處理響應和工具調用
tool_results = []
final_text = []
assistant_message_content = []
for content in response.content:
if content.type == 'text':
final_text.append(content.text)
assistant_message_content.append(content)
elif content.type == 'tool_use':
tool_name = content.name
tool_args = content.input
# 執行工具調用
result = await self.session.call_tool(tool_name, tool_args)
tool_results.append({"call": tool_name, "result": result})
final_text.append(f"[調用工具 {tool_name},參數 {tool_args}]")
assistant_message_content.append(content)
messages.append({
"role": "assistant",
"content": assistant_message_content
})
messages.append({
"role": "user",
"content": [
{
"type": "tool_result",
"tool_use_id": content.id,
"content": result.content
}
]
})
# 獲取 Claude 的下一個響應
response = self.anthropic.messages.create(
model="claude-3-5-sonnet-20241022",
max_tokens=1000,
messages=messages,
tools=available_tools
)
final_text.append(response.content[0].text)
return "\n".join(final_text)交互式聊天界面
現在添加聊天循環和清理功能:
async def chat_loop(self):
"""運行交互式聊天循環"""
print("\nMCP 客戶端已啟動!")
print("輸入你的查詢或 'quit' 退出。")
while True:
try:
query = input("\n查詢: ").strip()
if query.lower() == 'quit':
break
response = await self.process_query(query)
print("\n" + response)
except Exception as e:
print(f"\n錯誤: {str(e)}")
async def cleanup(self):
"""清理資源"""
await self.exit_stack.aclose()主入口點
最後,添加主執行邏輯:
async def main():
if len(sys.argv) < 2:
print("用法: python client.py <服務器腳本路徑>")
sys.exit(1)
client = MCPClient()
try:
await client.connect_to_server(sys.argv[1])
await client.chat_loop()
finally:
await client.cleanup()
if __name__ == "__main__":
import sys
asyncio.run(main())關鍵組件解釋
1. 客戶端初始化
MCPClient類初始化會話管理和 API 客戶端- 使用
AsyncExitStack進行資源管理 - 配置 Anthropic 客戶端以進行 Claude 交互
2. 服務器連接
- 支持 Python 和 Node.js 服務器
- 驗證服務器腳本類型
- 設置通信通道
- 初始化會話並列出可用工具
3. 查詢處理
- 維護對話上下文
- 處理 Claude 的響應和工具調用
- 管理 Claude 和工具之間的消息流
- 將結果組合成連貫的響應
4. 交互界面
- 提供簡單的命令行界面
- 處理用戶輸入並顯示響應
- 包含基本錯誤處理
- 允許正常退出
5. 資源管理
- 資源的正確清理
- 連接問題的錯誤處理
故障排除
服務器路徑問題
- 檢查服務器腳本路徑是否正確
- 如果相對路徑不起作用,請使用絕對路徑
- 對於 Windows 用戶,確保使用正斜槓(/) 或轉義的反斜槓(\)
- 確認服務器文件具有正確的擴展名 (.py 用於 Python 或 .js 用於 Node.js)
正確路徑使用示例:
# 相對路徑
uv run client.py ./server/weather.py
# 絕對路徑
uv run client.py /Users/username/projects/mcp-server/weather.py
# Windows 路徑(兩種格式都可以)
uv run client.py C:/projects/mcp-server/weather.py
uv run client.py C:\\projects\\mcp-server\\weather.py響應時間
- 第一個響應可能需要長達 30 秒
- 這是正常現象,發生在以下情況下:
- 服務器初始化
- Claude 處理查詢
- 工具執行
- 後續響應通常更快
- 在初始等待期間不要中斷進程
ℹ️
這是基於 Spring AI MCP 自動配置和啟動器的快速入門演示。
要了解如何手動創建同步和異步 MCP 客戶端,請查閱 Java SDK 客戶端 文檔
系統要求
開始之前,請確保你的系統滿足以下要求:
- Java 17 或更高版本
- Maven 3.6 或更高版本
- 支持 Spring Boot 的 IDE
創建項目
使用 Maven 創建一個新的 Spring Boot 項目:
mvn archetype:generate \
-DgroupId=com.example \
-DartifactId=ai-mcp-brave-chatbot \
-DarchetypeArtifactId=maven-archetype-quickstart \
-DinteractiveMode=false更新你的 pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>ai-mcp-brave-chatbot</artifactId>
<version>0.0.1-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.0</version>
</parent>
<properties>
<java.version>17</java.version>
<spring-ai.version>0.8.0</spring-ai.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-anthropic-spring-boot-starter</artifactId>
<version>${spring-ai.version}</version>
</dependency>
<dependency>
<groupId>org.modelcontext</groupId>
<artifactId>mcp-spring-boot-starter</artifactId>
<version>0.4.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>應用配置
在 application.yml 中添加以下配置:
spring:
ai:
anthropic:
api-key: ${ANTHROPIC_API_KEY}
mcp:
servers:
filesystem:
command: npx
args:
- "-y"
- "@modelcontextprotocol/server-filesystem"
- "C:\\Users\\username\\Desktop"
- "C:\\Users\\username\\Downloads"創建應用
創建主應用類:
package com.example;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class BraveChatApplication {
public static void main(String[] args) {
SpringApplication.run(BraveChatApplication.class, args);
}
}運行應用
# 構建並運行
./mvnw clean install
java -jar ./target/ai-mcp-brave-chatbot-0.0.1-SNAPSHOT.jar
# 另一種方式
./mvnw spring-boot:run在運行應用之前,請記得設置你的
ANTHROPIC_API_KEY 環境變量!工作原理
該應用通過多個組件將 Spring AI 與 MCP 服務器集成:
MCP 客戶端配置
pom.xml中的必需依賴項:
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-mcp-client-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-anthropic-spring-boot-starter</artifactId>
</dependency>- 應用屬性(
application.yml):
spring:
ai:
mcp:
client:
enabled: true
name: brave-search-client
version: 1.0.0
type: SYNC
request-timeout: 20s
stdio:
root-change-notification: true
servers-configuration: classpath:/mcp-servers-config.json
anthropic:
api-key: ${ANTHROPIC_API_KEY}- MCP 服務器配置(
mcp-servers-config.json):
{
"mcpServers": {
"brave-search": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-brave-search"
],
"env": {
"BRAVE_API_KEY": "<PUT YOUR BRAVE API KEY>"
}
}
}
}聊天實現
聊天機器人使用 Spring AI 的 ChatClient 與 MCP 工具集成:
var chatClient = chatClientBuilder
.defaultSystem("You are useful assistant, expert in AI and Java.")
.defaultTools((Object[]) mcpToolAdapter.toolCallbacks())
.defaultAdvisors(new MessageChatMemoryAdvisor(new InMemoryChatMemory()))
.build();主要功能:
- 使用 Claude AI 模型進行自然語言理解
- 集成 MCP 提供工具功能
- 使用 InMemoryChatMemory 維護對話記憶
- 作為交互式命令行應用運行
高級配置
MCP 客戶端支持其他配置選項:
- 通過
McpSyncClientCustomizer或McpAsyncClientCustomizer自定義客戶端 - 支持多種傳輸類型:
STDIO和SSE(服務器發送事件) - 與 Spring AI 的工具執行框架集成
- 自動客戶端初始化和生命週期管理
對於基於 WebFlux 的應用,可以使用 WebFlux 啟動器:
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-mcp-client-webflux-spring-boot-starter</artifactId>
</dependency>這提供了類似的功能,但使用基於 WebFlux 的 SSE 傳輸實現,推薦用於生產部署。