議實現(xiàn)天氣預報工具插件:TaoToken統(tǒng)一Key接入與config.toml配置骨架)
1. 為什么要在 Spring AI 里用 MCP 接天氣預報如果你正在用 Spring AI 做 Java 后端的大模型應用大概率會遇到一個很現(xiàn)實的問題模型本身不知道今天長沙多少度、明天北京下不下雨而你又不想把天氣查詢邏輯硬編碼進業(yè)務代碼里。MCPModel Context Protocol模型上下文協(xié)議就是來解決這類外部能力接入問題的——它把工具調(diào)用標準化讓大模型通過統(tǒng)一協(xié)議發(fā)現(xiàn)并調(diào)用你注冊的工具方法不用為每個工具寫一套定制化的函數(shù)調(diào)用代碼。Spring AI 從 1.1.x 開始原生支持 MCP服務端自動注冊、客戶端自動發(fā)現(xiàn)、工具一鍵綁定Java 開發(fā)者用幾個注解就能把普通業(yè)務方法變成 MCP 標準工具。這篇聚焦一個具體場景用 Spring AI MCP 協(xié)議做一個天氣預報工具插件同時把大模型通道統(tǒng)一走 TaoToken 的 Key 和 API 地址避免在多個模型供應商之間來回切換配置。適合已經(jīng)寫過 Spring Boot、想快速把 MCP 工具鏈路跑通的 Java 后端開發(fā)者。整篇的節(jié)奏是先講清楚 MCP 服務端和客戶端各自要做什么再給出 TaoToken 統(tǒng)一 Key 的 config.toml 配置骨架然后是服務端工具注冊、客戶端調(diào)用鏈路的可復制配置最后用一次本地啟動驗證確認插件能被正常發(fā)現(xiàn)和調(diào)用。你跟著做能拿到一個可運行的天氣預報 MCP 插件骨架。2. TaoToken 前置統(tǒng)一 Key 與 API 通道準備在動手寫 MCP 代碼之前先把大模型通道這塊理清楚。MCP 客戶端最終是要調(diào)用大模型的而大模型調(diào)用需要一個穩(wěn)定的 API 入口和 Key。TaoToken 在這里扮演的角色是統(tǒng)一 Key 和 API 通道——你不用為每個模型單獨維護一套 base-url 和 key而是通過一個統(tǒng)一的入口來管理。你需要先拿到一個可用的 API Key。登錄 TaoToken 官網(wǎng)https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content進入控制臺創(chuàng)建 API Key控制臺入口https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_contentconsoleAPI Keys 管理https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keys創(chuàng)建好 Key 之后API 的基礎地址是https://taotoken.net/api注意這個地址不加 UTM 參數(shù)直接用于代碼里的 base-url。這個地址兼容 OpenAI 風格的接口所以 Spring AI 的spring-ai-starter-openai可以直接對接只需要把 base-url 指過來、api-key 換成你的 TaoToken Key 即可。注意MCP 工具調(diào)用依賴大模型的 Function Calling 能力選模型時要確認它支持函數(shù)調(diào)用否則工具不會被觸發(fā)。你可以在模型對話頁面先驗證一下模型是否正常響應https://taotoken.net/model-chat?utm_sourcetaotoken_aicg_blog_endutm_contentmodel-chat如果你后續(xù)要做長期的編碼或 Agent 類任務可以考慮 Coding Plan它更適合持續(xù)性的開發(fā)場景https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding-plan3. config.toml 配置骨架與 MCP 服務端搭建3.1 config.toml 配置骨架很多 MCP 客戶端包括一些 IDE 和命令行工具用config.toml來聲明 MCP 服務端。下面是一個可直接復用的骨架把天氣預報 MCP 服務端以 stdio 方式注冊進去同時把大模型通道指向 TaoToken# config.toml - MCP 客戶端配置骨架 # 大模型通道統(tǒng)一走 TaoToken [llm] provider openai-compatible base_url https://taotoken.net/api api_key sk-你的TaoTokenKey model gpt-4o-mini # 換成你賬號下支持 Function Calling 的模型 temperature 0.1 # MCP 服務端注冊天氣預報插件stdio 方式 [mcp_servers.weather] command java args [ -Dfile.encodingUTF-8, -Dsun.jnu.encodingUTF-8, -jar, D:/springboot-ai-mcp-server-0.0.1-SNAPSHOT.jar ] enabled true # 可選SSE 方式注冊開發(fā)調(diào)試用 [mcp_servers.weather_sse] url http://localhost:8088/sse enabled false這個骨架里有兩塊關鍵信息[llm]段負責大模型通道base_url指向 TaoToken 的 API 地址[mcp_servers.weather]段負責把天氣預報 MCP 服務端注冊進來stdio 方式適合本地 jar 直接拉起SSE 方式適合服務端已經(jīng)獨立跑起來、通過 HTTP 長連接接入的場景。3.2 MCP 服務端 pom.xml服務端的職責是把普通 Java 方法封裝成 MCP 標準工具。先建一個 Maven 項目pom.xml 核心依賴如下parent groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-parent/artifactId version3.5.11/version /parent properties java.version17/java.version spring-ai.version1.1.4/spring-ai.version /properties dependencyManagement dependencies dependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-bom/artifactId version${spring-ai.version}/version typepom/type scopeimport/scope /dependency /dependencies /dependencyManagement dependencies dependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-starter-mcp-server-webmvc/artifactId /dependency dependency groupIdorg.projectlombok/groupId artifactIdlombok/artifactId optionaltrue/optional /dependency /dependencies版本這塊要卡死Spring Boot 3.5.11 配 Spring AI 1.1.4JDK 17 起步。版本錯配最常見的表現(xiàn)是自動配置類不生效啟動時看不到 MCP 相關 Bean。3.3 服務端 application.yml服務端支持兩種傳輸方式stdio 適合被客戶端以子進程方式拉起SSE 適合獨立部署。SSE 方式的配置server: port: 8088 spring: application: name: springboot-ai-mcp-server main: web-application-type: servlet ai: mcp: server: enabled: true name: 天氣預報 MCP 插件 version: 1.0.0 type: async sse-endpoint: /sse sse-message-endpoint: /mcp/message logging: level: org.springframework.ai.mcp: DEBUGstdio 方式則把web-application-type設為none并加上stdio: true同時把控制臺日志關掉避免日志污染 stdio 通道。3.4 自定義 MCP 工具核心代碼就一個類用Tool和ToolParam注解把方法暴露成 MCP 工具Component Slf4j public class WeatherMcpTool { private final WeatherService weatherService; public WeatherMcpTool(WeatherService weatherService) { this.weatherService weatherService; } Tool( name get_current_weather, description 獲取指定城市的實時天氣信息包括當前溫度、濕度、風速、天氣描述。 適用場景用戶詢問現(xiàn)在某地天氣怎么樣、某地熱不熱時調(diào)用。 ) public String getCurrentWeather( ToolParam(description 城市名稱支持中文或英文例如北京、長沙、London) String city ) { log.info([MCP Tool] 收到調(diào)用請求city{}, city); WeatherResponse weather weatherService.getWeather(city); return weather.toSummary(); } }工具描述要寫清楚大模型是靠 description 判斷要不要調(diào)用、怎么傳參的。描述模糊工具大概率不會被觸發(fā)。3.5 注冊工具回調(diào)再寫一個配置類把工具對象注冊成ToolCallbackProviderConfiguration public class McpServerConfig { Bean public ToolCallbackProvider weatherTools(WeatherMcpTool weatherMcpTool) { return MethodToolCallbackProvider.builder() .toolObjects(weatherMcpTool) .build(); } }啟動類就是標準 Spring Boot 啟動類啟動后訪問http://localhost:8088/sse能看到 SSE 長連接建立說明服務端正常。4. MCP 客戶端接入與調(diào)用鏈路4.1 客戶端 pom.xml客戶端負責對接服務端、自動發(fā)現(xiàn)工具、綁定到 ChatClient。核心依賴dependencies dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-web/artifactId /dependency dependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-starter-mcp-client/artifactId /dependency dependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-starter-openai/artifactId /dependency /dependencies4.2 客戶端 application.yml這里把大模型通道指向 TaoTokenMCP 客戶端通過 stdio 拉起服務端 jarserver: port: 8080 spring: application: name: springboot-ai-mcp-client ai: openai: api-key: sk-你的TaoTokenKey base-url: https://taotoken.net/api chat: options: model: gpt-4o-mini temperature: 0.1 mcp: client: toolcallback: enabled: true transports: - type: stdio command: java args: - -jar - D:/springboot-ai-mcp-server-0.0.1-SNAPSHOT.jar logging: level: org.springframework.ai.mcp: DEBUG org.springframework.ai.tool: DEBUGbase-url指向 TaoToken 的 API 地址api-key換成你在控制臺創(chuàng)建的 Key。MCP 客戶端啟動時會自動連接服務端、拉取工具列表。4.3 對話接口寫一個 Controller把 MCP 工具回調(diào)綁定到 ChatClientRestController public class WeatherController { private final ChatClient chatClient; public WeatherController(ChatClient.Builder builder, SyncMcpToolCallbackProvider mcpToolProvider) { this.chatClient builder .defaultToolCallbacks(mcpToolProvider.getToolCallbacks()) .build(); } GetMapping(/weather) public String queryWeather(RequestParam String city) { return chatClient.prompt() .user( 查詢 %s 的實時天氣。 必須調(diào)用 get_current_weather 工具不要用自身知識回答。 工具返回后直接原樣返回結果。 .formatted(city)) .call() .content(); } }SyncMcpToolCallbackProvider會自動把服務端發(fā)現(xiàn)的工具注入進來defaultToolCallbacks綁定后大模型在對話中就能自動判斷并調(diào)用。5. 本地啟動驗證與成功結果啟動順序很重要先起服務端確認 8088 端口正常再起客戶端??蛻舳藛尤罩纠锶绻芸吹?MCP 工具發(fā)現(xiàn)相關的 DEBUG 輸出說明工具已經(jīng)被拉取到了。然后訪問curl http://localhost:8080/weather?city長沙預期返回類似長沙當前的天氣為26℃多云南風3級濕度68%。如果返回的是模型自己編的天氣說明工具沒被調(diào)用。這時候去看客戶端日志里有沒有get_current_weather的調(diào)用記錄以及服務端日志里有沒有[MCP Tool] 收到調(diào)用請求。兩邊日志對上了鏈路就通了。你也可以在模型對話頁面單獨驗證模型通道是否正常https://taotoken.net/model-chat?utm_sourcetaotoken_aicg_blog_endutm_contentmodel-chat6. 本篇常見錯排查工具沒被調(diào)用模型直接回答最常見的原因是模型不支持 Function Calling或者工具 description 寫得太模糊。先確認模型支持函數(shù)調(diào)用再把 description 寫具體明確適用場景??蛻舳藛訄筮B接失敗stdio 方式要確認 jar 路徑正確、jar 已經(jīng) package 過SSE 方式要確認服務端先起來了、端口沒被占用。路徑里的反斜杠在 yaml 里要注意轉(zhuǎn)義。版本沖突導致自動配置失效Spring AI 1.1.4 必須配 Spring Boot 3.5.xJDK 17 起步。版本不對會出現(xiàn) MCP 相關 Bean 找不到的情況。SSE 連接超時生產(chǎn)環(huán)境要調(diào)整 connect-timeout 和 read-timeout網(wǎng)絡波動會導致長連接斷開。工具入?yún)惓CP 工具方法內(nèi)部要做參數(shù)校驗大模型可能傳過來空值或異常格式不校驗會直接拋異常。接入相關的文檔可以在這里查https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdoc7. 繼續(xù)往下走天氣預報這個例子跑通之后你可以把同樣的骨架套到其他工具上——數(shù)據(jù)庫查詢、內(nèi)部 API 調(diào)用、文件操作都是把方法加上Tool注解、注冊成ToolCallbackProvider就行。MCP 的價值在于工具接入標準化服務端和客戶端解耦工具換了大模型也不用改調(diào)用代碼。如果你要長期做編碼或 Agent 類任務Coding Plan 會更合適https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding-planAPI Key 管理和接入文檔分別在這里API Keyshttps://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keys接入文檔https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdoc先把服務端和客戶端兩個項目跑起來確認/weather?city長沙能返回真實天氣再往里面加你自己的工具。鏈路通了之后剩下的就是業(yè)務邏輯的事。