用 Solon AI 从零构建 MCP 工具服务:让 AI Agent 拥有真实世界的能力(TaoToken 统一 Key 接入版)
1. 为什么 Java 开发者需要自己写 MCP 工具服务你可能已经用过不少 AI 助手它们聊天很流畅但一旦你问「帮我查一下今天北京的天气」「把这条记录写进数据库」它们就开始含糊其辞。原因很简单模型本身只活在文本世界里它没有手也没有脚。MCPModel Context Protocol就是给模型装上手和脚的那套协议它定义了 AI 模型如何发现并调用外部工具——查天气、读文件、发请求、操作数据库都通过统一的工具描述暴露给模型。对 Java 开发者来说这件事以前有点尴尬。主流 MCP 示例大多用 Python 或 TypeScript 写Java 生态里要么依赖 Spring Boot 那一整套重配置要么得自己手搓 JSON-RPC。Solon AI 的出现改变了这个局面它基于 Solon 框架启动快、依赖少用McpTool注解就能把一个普通 Java 方法变成 AI 可调用的工具。你不需要理解协议底层的握手细节框架会帮你把方法签名、参数说明转成模型能读懂的 JSON Schema。这篇文章要交付的是一条完整链路用 Solon AI 搭一个 MCP 工具服务定义McpTool本地启动再通过 TaoToken 的统一 Key 和 API 通道把模型接进来让 Agent 真正调用你写的工具。适合谁有 Java 基础、想给 AI Agent 加真实世界能力、又不想被重型框架拖住的开发者。读完你能拿到可复制的工程骨架、配置片段和验证命令而不是一堆概念。我试过用纯手写 JSON-RPC 的方式对接模型光是处理工具描述和参数校验就写了两百多行换成 Solon AI 之后核心代码不到三十行。下面从环境准备开始一步步来。2. TaoToken 统一 Key 与 Solon AI 工程骨架准备在写工具之前先把「模型从哪来」这件事解决掉。MCP 服务本身只负责暴露工具真正决定调用哪个工具的是背后的模型。你需要一个能稳定访问模型 API 的通道TaoToken 在这里扮演的就是统一入口的角色一个 Key、一个 Base URL就能对接多种模型省去你在多个平台之间来回切换配置的麻烦。TaoToken 的官网是 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content API 地址是 https://taotoken.net/api 。注意 API 地址后面不加任何查询参数保持干净。你需要先去控制台创建一个 API Key路径在 https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_contentconsoleutm_campaignrewrite 创建好的 Key 在 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite 管理。如果你只是想先验证模型通不通可以用模型对话页面 https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_contentchatutm_campaignrewrite 快速试一句。工程骨架用 Maven 构建JDK 17 起步。pom.xml里加三个依赖Solon AI 核心、Solon Web用来起 HTTP 服务、fastjson2解析工具返回的 JSON。版本号建议用 2.7.x 系列和 Solon 主版本对齐。dependencies dependency groupIdorg.noear/groupId artifactIdsolon-ai/artifactId version2.7.0/version /dependency dependency groupIdorg.noear/groupId artifactIdsolon-web/artifactId version2.7.0/version /dependency dependency groupIdcom.alibaba.fastjson2/groupId artifactIdfastjson2/artifactId version2.0.40/version /dependency /dependencies目录结构保持简单src/main/java下放启动类和工具类src/main/resources下放app.yml配置文件。Solon 默认会扫描启动类所在包及其子包所以工具类放在启动类同级或子包里都能被自动发现。配置文件app.yml里写两件事服务端口和模型接入信息。模型这块用 TaoToken 的 Base URL 和你的 Key。注意 Key 不要硬编码进代码提交到仓库用环境变量或者本地配置文件这里为了演示直接写在 yml 里你实际用的时候记得换成${TAOTOKEN_API_KEY}这种占位。server: port: 8080 solon: ai: model: base-url: https://taotoken.net/api api-key: ${TAOTOKEN_API_KEY} model-id: claude-sonnet-4-20250514这里model-id填你实际要用的模型标识TaoToken 支持多种模型具体可用的 ID 在文档 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 里查。Base URL、Key、Model ID 这三件套是后面所有配置的基础缺一不可。如果你用的是 Claude Code 这类工具配置方式类似只是文件位置不同Claude Code 的接入说明在 https://taotoken.net/claudecode?utm_sourcetaotoken_aicg_blog_endutm_contentclaudecodeutm_campaignrewrite 。环境准备好之后先别急着写复杂工具从最小的可运行服务开始确认 Solon 能起来、MCP 端点能响应再往上叠功能。这样出问题的时候排查范围小。3. 可复制的 McpTool 定义与 settings 配置片段现在进入核心部分定义工具。Solon AI 的工具定义靠两个注解——McpTool标在方法上McpParam标在参数上。框架会读取这些注解生成模型能理解的工具描述。描述写得越清楚模型选对工具、填对参数的概率越高。先写一个计算器工具验证整条链路。类上加Component让 Solon 扫描到方法上加McpTool每个参数加McpParam。import org.noear.solon.annotation.Component; import org.noear.solon.ai.mcp.annotation.McpTool; import org.noear.solon.ai.mcp.annotation.McpParam; Component public class CalculatorTools { McpTool(description 执行数学计算支持加、减、乘、除四则运算) public String calculate( McpParam(description 第一个数字) double a, McpParam(description 操作符可选 - * /) String operator, McpParam(description 第二个数字) double b) { double result; switch (operator) { case : result a b; break; case -: result a - b; break; case *: result a * b; break; case /: if (b 0) return 错误除数不能为零; result a / b; break; default: return 错误不支持的操作符 operator; } return String.format(%.2f %s %.2f %.2f, a, operator, b, result); } }启动类里把 Solon 跑起来MCP 端点默认挂在/mcp你也可以改。import org.noear.solon.Solon; public class McpServerApp { public static void main(String[] args) { Solon.start(McpServerApp.class, args); } }接下来是配置片段。如果你用的是支持 MCP 的客户端比如某些 IDE 插件或 Agent 工具它们通常读一个settings.json或类似的配置文件来发现 MCP 服务。下面这段是通用的 MCP 服务注册格式把本地 Solon 服务注册进去同时把模型通道指向 TaoToken。{ mcpServers: { solon-tools: { url: http://localhost:8080/mcp, transport: http } }, model: { baseUrl: https://taotoken.net/api, apiKey: 你的TaoToken Key, modelId: claude-sonnet-4-20250514 } }注意baseUrl是https://taotoken.net/api不要加多余的路径。apiKey从 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite 拿。modelId按你实际用的模型填。这三件套——Base URL、Key、Model ID——在任何 MCP 客户端里都是必须的格式可能略有差异但字段含义一致。如果你用的是 Codex 这类工具它的auth.json里也是类似的三件套结构只是字段名可能叫base_url、api_key、model。Cline 的 MCP 配置则是在插件设置里填服务地址和模型信息。不管哪种核心都是把「工具服务地址」和「模型通道」两件事配清楚。工具描述里有个细节值得注意description不要写得太笼统。比如「查询天气」不如「查询指定城市的实时天气返回温度、湿度、天气状况」来得有用。模型是靠这段文字判断该不该调用这个工具的描述越具体误调用越少。参数描述同理McpParam里写清楚单位、格式、可选值能省掉很多模型填错参数的麻烦。4. 本地启动与 Agent 调用验证请求配置写完启动服务。命令行里跑mvn compile exec:java或者直接在 IDE 里运行McpServerApp的 main 方法。看到 Solon 打印出启动日志、端口 8080 监听成功就说明服务起来了。先用 curl 直接打 MCP 端点确认工具能被调用。MCP over HTTP 的请求体格式是 JSON-RPC 风格工具名和参数放在params里。curl -X POST http://localhost:8080/mcp \ -H Content-Type: application/json \ -d { jsonrpc: 2.0, id: 1, method: tools/call, params: { name: calculate, arguments: {a: 10, operator: , b: 5} } }正常返回应该包含10.00 5.00 15.00这个结果。如果返回的是工具列表而不是执行结果说明你调的是tools/list方法换成tools/call再试。这一步验证的是「工具服务本身能不能被调用」和模型无关。接下来验证模型能不能通过 TaoToken 通道调用这个工具。用模型对话页面 https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_contentchatutm_campaignrewrite 发一句「用计算器算一下 10 加 5」如果模型配置正确、工具注册正确它会返回工具调用请求你的 Solon 服务执行后把结果回传模型再组织成自然语言回答。如果你想在代码里验证可以用 Solon AI 的客户端能力发一个带 tools 的请求。核心是把 MCP 服务的工具描述作为tools参数传给模型模型返回tool_calls时你解析出工具名和参数调用本地 MCP 端点再把结果塞回对话。// 伪代码示意调用流程 // 1. 从 MCP 服务拉取工具列表 // 2. 把工具列表转成模型 API 的 tools 参数 // 3. 发送用户消息 tools 给 https://taotoken.net/api // 4. 解析返回的 tool_calls执行本地工具 // 5. 把工具结果作为新消息回传拿到最终回答实测下来最容易出问题的环节是工具描述和模型理解之间的偏差。比如你写了个getWeather工具但描述里没说是「实时」天气模型可能在你问「明天天气」时也调用它结果返回的是当前天气。解决办法是在描述里明确边界或者在工具内部对参数做校验返回清晰的错误提示让模型自己纠正。验证通过后你可以把计算器换成真实工具。比如查天气用 Java 原生HttpClient调外部 API解析 JSON 返回格式化字符串。注意外部 API 的 Key 不要和 TaoToken 的 Key 混在一起各管各的。工具方法里做好异常捕获网络超时、返回码非 200 这些情况都要返回人类可读的错误信息模型拿到错误信息后往往能自己决定重试还是换工具。5. 常见报错排查401、local proxy failed 与 reading choices接入过程中有几类报错出现频率很高这里逐个拆解。401 Unauthorized。这个最直接Key 不对或者没传。检查三件事apiKey字段有没有填、Key 有没有多余空格、Key 是不是从正确的控制台页面复制的。TaoToken 的 Key 在 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite 管理如果你在别的地方复制了旧 Key可能已经失效。另外注意 Base URL 必须是https://taotoken.net/api写成https://taotoken.net/api/v1之类的路径可能导致鉴权失败。local proxy failed。这个报错通常出现在客户端尝试连接 MCP 服务时。原因一般是服务地址写错或者服务没起来。先确认http://localhost:8080/mcp这个地址在浏览器或 curl 里能通。如果服务起来了但客户端连不上检查客户端配置里的url字段有没有拼错端口是不是被占用。Solon 默认端口 8080如果你本机 8080 被别的程序占了改app.yml里的server.port同时更新客户端配置。reading choices 相关报错。这类错误一般出现在解析模型返回时提示读取choices字段失败。根因通常是模型返回的不是标准对话格式可能是返回了错误信息、或者返回结构和你代码里解析的字段不匹配。排查方法先把原始返回打印出来看确认choices数组存不存在。如果返回的是error字段那问题在请求侧检查模型 ID 是否正确、请求体格式是否符合预期。TaoToken 的文档 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 里有各模型的请求格式说明对照检查。OAuth 相关报错。如果你用的是 Claude Code 这类带 OAuth 流程的工具报错可能提示 token 过期或授权失败。这类工具通常有自己的登录命令重新走一遍授权流程即可。注意 OAuth 和 API Key 是两套体系不要混用。Claude Code 的接入方式在 https://taotoken.net/claudecode?utm_sourcetaotoken_aicg_blog_endutm_contentclaudecodeutm_campaignrewrite 有说明按步骤配置 Base URL 和 Key。工具调用返回空或超时。检查工具方法里有没有阻塞操作。比如调外部 API 没设超时网络慢的时候会一直挂着。给HttpClient设个连接超时和读取超时比如 5 秒和 10 秒。另外工具方法的返回类型建议用String返回结构化 JSON 字符串模型解析起来更稳。如果返回的是复杂对象确保序列化没问题。排查顺序建议从外到内先确认 MCP 服务本身能通过 curl 调用再确认模型通道能通用模型对话页面发一句简单的话最后确认两者串起来时工具描述和参数匹配。大部分问题出在配置文件的字段拼写和地址格式上仔细核对三件套——Base URL、Key、Model ID。6. 把工具服务接到长期编码与 Agent 工作流工具服务跑通之后下一步是让它进入你的日常工作流。如果你只是偶尔验证一下用模型对话页面就够了。但如果你想让 Agent 在编码、调试、查文档这些场景里持续调用你的工具就需要一个稳定的通道和足够的调用额度。TaoToken 的 Coding Plan 就是为这种长期编码和 Agent 场景准备的地址在 https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding-planutm_campaignrewrite 。接入方式和你前面配的三件套一致Base URL 用https://taotoken.net/apiKey 用你在控制台创建的 KeyModel ID 按需选择。区别在于 Coding Plan 更适合高频、长时间的 Agent 调用不用每次担心额度问题。对于 MCP 工具服务这种「模型频繁决策、工具频繁执行」的场景稳定的通道比什么都重要。你可以把 Solon AI 的 MCP 服务打包成 jar用java -jar在后台跑然后让 Agent 客户端指向这个本地服务。工具可以逐步扩展查数据库、读本地文件、调内部 API、发通知。每加一个工具就在类上加Component方法上加McpTool重启服务Agent 就能发现新工具。Solon 的扫描机制让这个过程很轻不需要改配置文件。有个实用技巧给工具方法加日志记录每次调用的参数和返回。这样当模型选错工具或者填错参数时你能从日志里看到它到底传了什么反过来优化McpTool的描述。工具描述不是写一次就完事的根据实际调用情况迭代几轮命中率会明显提升。最后一步验证在 Agent 客户端里发一个需要多步工具调用的任务比如「查一下北京天气然后算一下温度换算成华氏度是多少」。如果模型能先调天气工具拿到摄氏温度再调计算器工具做换算最后组织成回答说明整条链路——Solon AI 工具服务、TaoToken 模型通道、Agent 决策——全部打通了。到这一步你的 AI Agent 就不再只是聊天而是真正能动手做事了。

相关新闻

Claude Code之回滚:把 settings 改到 TaoToken 后如何优雅撤销一次会话改动

Claude Code之回滚:把 settings 改到 TaoToken 后如何优雅撤销一次会话改动

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/30 21:19:21 阅读更多 →
面向六个月后的 AI Code,TaoToken 统一 Key 通道如何影响的不只是前端

面向六个月后的 AI Code,TaoToken 统一 Key 通道如何影响的不只是前端

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/30 21:19:21 阅读更多 →
Vibe Coding 开发鸿蒙应用APP:前言篇·TaoToken 统一 Key 接入与学习路线指南

Vibe Coding 开发鸿蒙应用APP:前言篇·TaoToken 统一 Key 接入与学习路线指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/30 21:19:21 阅读更多 →

最新新闻

AI 前沿日报:2026年8月15日|Qwen3.8-27B 本地跑通与 TaoToken 统一 Key 配置

AI 前沿日报:2026年8月15日|Qwen3.8-27B 本地跑通与 TaoToken 统一 Key 配置

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/30 23:47:22 阅读更多 →
传统产品经理转AI产品经理,原来的能力哪些能保留,哪些必须重学?

传统产品经理转AI产品经理,原来的能力哪些能保留,哪些必须重学?

传统产品经理转型AI产品经理并非全盘推翻原有能力体系,而是底层通用能力完整保留,核心技术业务能力全面重构。传统PM积累的需求洞察、用户思维、商业拆解、项目推进四大核心能力,是AI产品经理开展工作的基础底盘,无需重复学习&…

2026/9/30 23:47:22 阅读更多 →
UltraEdit-32 V14.20 注册码验证有效:TaoToken 统一 Key 通道下的授权配置与校验

UltraEdit-32 V14.20 注册码验证有效:TaoToken 统一 Key 通道下的授权配置与校验

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/30 23:47:22 阅读更多 →
电赛工程化实战:从元器件选型到四天三夜系统设计复盘

电赛工程化实战:从元器件选型到四天三夜系统设计复盘

电赛收官季总是最热闹的,省赛评分刚过、国赛名单还在发酵,很多队伍已经开始为下一届做技术储备。就在这几天,贸泽助力电赛的系列直播课程也正式收官了。我一路跟下来,最大的感受是:这套课程没有把重点放在“教你背知识…

2026/9/30 23:47:22 阅读更多 →
我花三天实测了DeepSeek V4,发现它根本不是来跟GPT-4o打架的:一份TaoToken统一Key接入配置实录

我花三天实测了DeepSeek V4,发现它根本不是来跟GPT-4o打架的:一份TaoToken统一Key接入配置实录

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/30 23:47:22 阅读更多 →
PLC会中病毒吗?解析恶意代码入侵路径与现场防御策略

PLC会中病毒吗?解析恶意代码入侵路径与现场防御策略

上周接到一个做设备维护的朋友打来的电话:产线上一个工位偶尔会自己多动作一次,时好时坏。换了传感器、查了接线,问题依旧。我让他用编程软件打开在线监视程序,翻了一会儿,发现梯形图里多了一个谁都没印象的计数器逻辑…

2026/9/30 23:46:22 阅读更多 →

日新闻

Base64 图片头部特征识别:从文件头到格式判断的完整指南

Base64 图片头部特征识别:从文件头到格式判断的完整指南

1. 项目概述:为什么说看懂 base64 图片头部是基本功这几年跟 base64 打交道的机会越来越多,后端接口返回图片、前端渲染验证码、小程序里存小图、还有一些老系统导出报表,动不动就给你一段长到怀疑人生的 base64 字符串。很多人拿到字符串就直…

2026/9/30 0:00:35 阅读更多 →
Java公交站牌广告管理系统:JSP+Servlet+MySQL实战落地指南

Java公交站牌广告管理系统:JSP+Servlet+MySQL实战落地指南

简介:本资源是一份面向Java初学者与课程设计学生的公交站牌广告灯箱管理系统毕业设计文档,聚焦城市公共广告资源信息化管理痛点,提供从需求分析到技术实现的完整方案。文档采用标准学术论文结构,含摘要、英文摘要、目录及五章正文…

2026/9/30 0:00:35 阅读更多 →
用 Redis Lua 构建大模型 API 多租户原子配额治理体系

用 Redis Lua 构建大模型 API 多租户原子配额治理体系

我去年年底接了一个内部 AI 平台的治理需求,背景很直接:公司把 DeepSeek、MiniMax 这类大模型 API 统一封装成内部网关,开放给几个业务团队用。结果第一个月账单出来,额度直接超了 4 倍。仔细查日志,发现原因并不复杂—…

2026/9/30 0:00:35 阅读更多 →

周新闻

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解 【免费下载链接】spirula-studio Cross-vendor 3D Gaussian Splatting trainer - video to splat to mesh, Vulkan or CUDA. 项目地址: https://gitcode.com/GitHub_Trending/sp/spirula-studio Sp…

2026/9/30 13:14:22 阅读更多 →
SEO怎么推广速查手册新手避坑实战指南

SEO怎么推广速查手册新手避坑实战指南

SEO怎么推广速查手册新手避坑实战指南 模板网站太丑不够用?别急着加滤镜,那是治标不治本。很多老板盯着后台流量掉得眼红,却还在纠结首页Banner的圆角是不是3像素。这就像穿着西装去挖土,姿势不对,努力白费。我整理这份 速查手册…

2026/9/30 18:13:06 阅读更多 →
FireRed-OpenStoryline少样本仿写深度解析:AI Agent如何复刻你的独特文案风格与节奏

FireRed-OpenStoryline少样本仿写深度解析:AI Agent如何复刻你的独特文案风格与节奏

FireRed-OpenStoryline少样本仿写深度解析:AI Agent如何复刻你的独特文案风格与节奏 【免费下载链接】FireRed-OpenStoryline FireRed-OpenStoryline is an AI video editing agent that transforms manual editing into intention-driven directing through natural language …

2026/9/30 13:14:49 阅读更多 →

月新闻

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

2026/9/29 19:29:29 阅读更多 →
容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…

2026/9/29 5:58:00 阅读更多 →
容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步分类:[工程技术]细分主题:Docker 容器化技术与镜像安全管理:核心链路的逐步实现与关键代码取舍面对一个积累了五六年历史包袱的单体架构应用(包含 Web 接口、后台…

2026/9/30 15:27:04 阅读更多 →