先别急着打开行情软件,这期训练营咱们来点硬核的:手把手把股票查询能力做成一个 MCP Server,然后让 Spring AI Alibaba 接上它。MCP 全称 Model Context Protocol,我习惯把它比作 AI 应用的“USB-C 接口”——任何遵守这个协议的 Agent 或大模型应用,都能直接插入你的股票查询工具,不用为每个框架单独写一套函数调用适配。这个实战非常适合正在学 Spring AI Alibaba 的同学、想把自己私有工具开放给大模型的后端开发者,以及纯粹对 MCP 好奇的 Java 工程师。我会从 MCP 原理讲起,再把工程搭建、工具封装、本地启动、客户端接入全链路走一遍,过程中会穿插我在调这个项目时踩过的坑。项目最终能做到:输入“帮我查一下贵州茅台今天涨了还是跌了”,大模型会自动调用你构建的 MCP Server 里的股票查询工具,返回真实的实时行情,而不是编一个数字糊弄你。
1. 项目整体设计思路:为什么非要用 MCP Server 包一层股票查询
1.1 在传统 Function Calling 和 MCP 之间,我为什么选后者
早些年做 AI 应用,最常见的做法是 Function Calling:在模型请求里声明一个函数列表,模型判断该调用哪个函数,然后你的代码去执行并回传结果。这套机制本身没什么问题,但有一个痛点:每个大模型厂商的函数协议都不一样,OpenAI 一套、Anthropic 一套、国内各家又是一套。你今天用 OpenAI 写好了工具调用逻辑,明天想切换到另一家模型,SDK 和参数结构全得重写。
MCP 的思路是把“暴露工具”这件事标准化。MCP Server 只负责声明自己有哪些工具,参数是什么类型,然后通过统一协议把工具列表和调用结果传给任何支持 MCP 的客户端。Spring AI Alibaba 自身支持多种模型,同时它也把 MCP 整合得很顺,这样一来,我的工具层就跟具体模型解耦了。以后我想从一个模型切到另一个模型,只需要调整客户端配置,业务工具代码一点不用动。
1.2 股票查询 MCP Server 的三种典型收益
第一个收益是复用。同一个股票查询 Server 构建出来后,可以同时被命令行工具、IDE 里的 AI 助手、你自建的 Web 应用甚至训练营里的小机器人调用。因为它是一个标准服务,不是嵌在某个应用里的代码块。
第二个收益是安全的收敛。实时行情接口往往需要鉴权、验签、限流,这些逻辑放在 MCP Server 里面统一处理,调用方不需要知道你的数据源密钥。这样就避免了把密钥下发到各种 Agent 客户端。我的实现里密钥只存在于 Server 环境变量里,客户端一个都不碰。
第三个收益是演进方便。先做实时行情,后面想加 K 线、分时图、公告、资金流向,只需要在同一个 MCP Server 里新增工具方法,客户端无需任何改动。工具的版本演进对调用方完全透明,这对于团队协作或者商业化 Agent 来说非常重要。
1.3 股票行情数据源选型分析
构建股票 MCP Server 离不开真实数据源。我在训练营里通常建议学员优先使用免费且稳定的 HTTP 接口,比如新浪财经接口和腾讯财经接口。新浪的 hq.sinajs.cn 和腾讯的 qt.gtimg.cn 都不需要复杂的鉴权,只需要注意请求头里的 Referer 和编码格式即可。这类接口适合学习和低成本演示,单机请求频率控制在 1 秒一次以内基本不会被封。
如果要做更严谨的商业应用,可以接券商或者专业行情服务商的付费接口,数据质量、延迟和稳定性会更好,但这些接口通常要求特定的网络环境或 Token 签发流程,不适合新手入门。我在这里的选型原则是:能用免费接口说明协议设计,就绝不用付费接口,等大家跑通全链路之后,再替换成专业数据源就是非常顺理成章的事。
我在设计股票查询工具时把工具粒度拆成了三个:股票代码搜索、实时行情查询、涨跌幅对比。代码搜索用来解决“用户只输入中文名,需要映射到标准股票代码”的问题;实时行情查询返回价格、涨跌幅、成交额等核心字段;涨跌幅对比则是组合调用,把两只股票的实时数据拉回来做横向比较。粒度拆得细,模型才更容易理解在什么场景下调用什么工具。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 核心原理:Spring AI Alibaba 里的 MCP Server 底座到底长什么样
2.1 一套协议,两种传输方式,本地启动怎么选
MCP 协议规定了客户端和服务器之间的通信方式,最常见的是两种传输:stdio 和 Streamable HTTP。
stdio 是指 MCP Server 作为本地子进程启动,客户端通过标准输入和标准输出与它通信。这种方式最大的优势是零网络配置,启动速度快,适合本地开发调试,以及像 Claude Desktop 这类桌面客户端内置扩展的场景。缺点也很明显:只能被本机进程访问,无法服务远程调用。
Streamable HTTP 则是通过 HTTP 长连接或者 POST 请求来传输 MCP 消息。Spring AI Alibaba 的 MCP 支持里,基于 WebMVC 和 WebFlux 的 HTTP 传输两种方式都有。如果你想做一个真正能给多个客户端并发使用的股票查询服务,建议走这种传输方式。我在训练营的实操环节中,本地直接启动调试用 stdio,部署到服务器供小组机器人调用时用 Streamable HTTP。
本地启动 MCP Server 教程的核心,就是先把 stdio 跑通。因为 stdio 模式没有网络端口,所以从直观上看日志非常少,很多人以为项目没启动成功,这是新手最容易误解的地方。实际上进程只要不退出,就说明 server 已经准备好,等着客户端通过标准输入来握手了。我稍后在第 3 节里会演示具体的验证办法。
2.2 Spring AI Alibaba 的 MCP 支持能力拆解
先回答一个很多学员都在问的问题:spring ai alibaba 停更了吗?从 Maven 中央仓库的版本时间线看,Spring AI Alibaba 目前依然保持活跃发版,并且新版本的更新重点基本都围绕多模型适配、企业级功能以及 MCP 工具调用集成。真正快速迭代的部分是把 Spring AI 的生态能力吸收进来,再针对国内模型和云环境做增强。所以你现在学习它构建 MCP Server,方向是对的,不存在因为项目停更导致白学的问题。
在 Spring AI 的模块体系里,MCP 相关的核心库是 spring-ai-starter-mcp-server 和 spring-ai-starter-mcp-client。Spring AI Alibaba 在模型适配层兼容这些模块,所以你写出来的 MCP Server 既可以跑在通义千问上,也可以跑在其它支持 Spring AI 的模型上。MCP Server 端负责提供和注册工具,MCP Client 端负责发现工具、调用工具、把结果喂回大模型。
Spring AI 的 MCP Server 支持 @Tool 注解。当你写一个方法并加上 @Tool(name="xxx", description="yyy"),框架会在启动时自动扫描这些方法,把方法签名转换成 MCP 标准协议里的工具定义,注册进 MCP Server 的工具清单里。调用者通过 MCP 协议发现的工具列表,就是由这些注解方法生成的 JSON Schema。如果你想动态注册工具,也可以手动构造 ToolSpecification,但我在实际开发中更倾向于用 @Tool 注解,因为代码直观,IDE 里也能直接定位。
2.3 工具定义的数据契约严谨度决定模型调用成功率
MCP 工具定义中的数据契约,直接决定了大模型能不能正确调用你的工具。我在训练营里反复强调一个观点:给大模型用的方法名和参数名,要以“模型能看懂”为第一优先级,而不是以“程序员写得顺手”为第一优先级。
举个例子,如果你写一个方法叫 query1(String p1),模型完全不知道这个工具是干什么的,参数 p1 是什么。但如果你写 @Tool(name="getStockRealtimeQuote", description="根据股票代码获取实时行情价格、涨跌幅、成交量"),参数是 stockCode,描述是 “沪深 A 股代码,如 sh600519”,模型就很容易把这个工具和用户的“查一下茅台”关联起来。MCP 工具描述越明确,模型误调用的概率越低,返回结果的准确率越高。
在 @Tool 方法的返回值处理上,Spring AI 会序列化成 JSON 文本返回给模型。这个结构也要尽量扁平。我见过有人把行情接口的原始返回直接塞回给模型,里面几十个字段、嵌套多层,模型在生成自然语言时经常把无用字段也带出来。最佳实践是只保留最重要的几个字段:股票名称、代码、最新价、涨跌额、涨跌幅、时间戳,必要时再加一个公告摘要。字段越少,模型越不会胡说。
3. 实操核心环节:从零构建一个可运行的股票查询 MCP Server
3.1 工程初始化与依赖版本搭配
我用 Java 17 和 Spring Boot 3.x 来搭建项目,这个搭配是 Spring AI 系列模块目前兼容性最好的组合。Maven 工程先创建好,然后在 pom.xml 里增加 MCP Server 相关的依赖。我这里直接给出一个精简可用的版本配置:
xml复制<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.3.4</version>
</parent>
<properties>
<java.version>17</java.version>
<spring-ai.version>1.0.0-M6</spring-ai.version>
</properties>
<dependencies>
<dependency>
<groupId>com.alibaba.cloud.ai</groupId>
<artifactId>spring-ai-alibaba-starter</artifactId>
<version>1.0.0.1</version>
</dependency>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-mcp-server</artifactId>
<version>${spring-ai.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-mcp-server-webmvc</artifactId>
<version>${spring-ai.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependency>
这里有一个容易踩坑的点:Spring AI 的版本迭代速度非常快,MCP 模块的包名和类名在不同里程碑版本之间变动过。我在训练营中带学员操作时遇到最多的问题,就是下载了一个网上旧版代码,结果 McpServer 的类名在最新版里已经换了位置。建议大家在搭建项目时,尽量以你当前依赖版本对应的 API 文档为准,代码写完之后先跑起来再深挖原理。
3.2 开发股票查询工具类,绑定新浪行情接口
我们用一个 StockToolService 来承载所有工具方法。这里以新浪接口为例,它返回的是 GBK 编码的文本数据,需要做编码转换和字段拆分。先看核心工具方法:
java复制@Component
public class StockToolService {
private final RestTemplate restTemplate = new RestTemplate();
@Tool(name = "searchStock", description = "根据股票中文名或代码搜索标准股票代码,如‘贵州茅台’返回sh600519")
public String searchStock(String keyword) {
// 演示用简化映射,真实场景建议维护一份代码表或调用搜索接口
if (keyword.contains("茅台")) {
return "sh600519";
}
if (keyword.contains("腾讯")) {
return "hk00700";
}
return "not_found";
}
@Tool(name = "getStockRealtimeQuote", description = "根据股票代码获取实时行情,返回名称、最新价、涨跌额、涨跌幅、成交额、时间")
public String getStockRealtimeQuote(String stockCode) {
String url = "https://hq.sinajs.cn/list=" + stockCode;
HttpHeaders headers = new HttpHeaders();
headers.set("Referer", "https://finance.sina.com.cn");
headers.set("User-Agent", "Mozilla/5.0");
HttpEntity<Void> entity = new HttpEntity<>(headers);
ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.GET, entity, String.class);
String body = response.getBody();
// 新浪返回格式:var hq_str_sh600519="贵州茅台,1700.00,1699.00,...";
String jsonStr = parseSinaQuote(body);
return jsonStr;
}
}
parseSinaQuote 里的解析逻辑并不复杂,关键是知道新浪行情文本的字段顺序:股票名称、今日开盘价、昨日收盘价、最新价、最高价、最低价、竞买价、竞卖价、成交量、成交额、日期、时间,等等。我建议初学者先用逗号把字符串拆开,取前几个字段拼成 JSON 返回。完整实现的代码我放在训练营的代码仓库里,这里主要讲解思路。
重点强调一下请求头。新浪这个接口如果不带 Referer 头,大概率返回 403。很多学员在自己电脑上能跑通,换了服务器就报错,多半是请求头的伪装问题。这个坑我在常见问题部分还会再提一次。
3.3 注册工具并配置 MCP 传输方式
有了工具类之后,需要把它注册到 MCP Server 上。我在配置类里显式创建工具回调注册表,把 StockToolService 里的 @Tool 方法收集起来。如果你使用的是 @Tool 注解,Spring AI 自动扫描机制会在启动时做好这件事,但为了可读性,我会手动配置一个 ToolCallbackProvider:
java复制@Configuration
public class McpServerConfig {
@Bean
public ToolCallbackProvider stockTools(StockToolService service) {
return MethodToolCallbackProvider.builder()
.toolObjects(service)
.build();
}
@Bean
public McpServerFeatures.SyncSpec syncSpec(ToolCallbackProvider toolCallbackProvider) {
return McpServer.using(transport())
.name("stock-mcp-server")
.version("1.0.0")
.tools(toolCallbackProvider)
.sync();
}
}
上面代码里的 transport() 是核心。如果只是本地调试,我直接用 StdioServerTransport;如果用 webmvc 依赖里的 HTTP 传输,可以创建一个 StreamableHttpServerTransport,然后指定一个路径,比如 /mcp。两种 transport 的配置很少,却直接影响后续调用方式。本地启动 MCP Server 教程里,我强烈推荐先从 StdioServerTransport 跑通,因为它不占用端口,逻辑最简单。
3.4 本地启动 MCP Server 的验证方法
正常启动 Spring Boot 应用后,在 stdio 模式下控制台只会输出 Spring Boot 的启动日志,不会打印任何“MCP Server 已启动”的提示。这时候不要慌,你要做的是外部用一个 MCP 客户端去连接它。最常用的工具是 MCP Inspector。安装方式很简单,通过 npm 运行:
bash复制npx @modelcontextprotocol/inspector --transport stdio -- java -jar target/stock-mcp-server.jar
Inspector 会启动一个本地 Web 页面,默认端口通常打印在终端里。打开页面后,先点击“Connect”,然后在左侧工具栏列表里就能看到 searchStock 和 getStockRealtimeQuote 两个工具。点击工具名,输入参数,例如 stockCode=sh600519,点 Call,右侧就会显示返回的实时行情 JSON。看到这一步,说明你的 MCP Server 已经真正跑通了。
在 Windows 上跑这个命令时要注意 mvn 打包后的 jar 路径,以及 Java 命令是否在 PATH 里。如果遇到 java 找不到,就用 --java "C:\Program Files\Java\jdk-17\bin\java.exe" 这样的全路径。这个提示看起来很小,但训练营中至少三分之一的人卡在环境问题上。
4. 客户端接入:让 Spring AI Alibaba 应用自动调用股票查询服务
4.1 新起一个 Spring AI Alibaba 客户端工程
MCP Server 构建完成后,下一步是让它融入一个真正的 AI 应用。你可以新起一个独立的 Spring Boot 工程作为客户端,也可以直接在同一个工程里既做 Server 又做 Client,但我不推荐后者,原因很简单:模块职责混在一起,以后部署要分开时就难拆了。
客户端项目需要引入 spring-ai-starter-mcp-client 和 spring-ai-alibaba-starter。配置文件里最关键的是告诉 Spring AI 去哪里找 MCP Server。如果 Server 是本地 stdio 模式,配置如下:
yaml复制spring:
ai:
mcp:
client:
stdio:
servers:
stock:
command: java
args: -jar, /path/to/stock-mcp-server.jar
如果 Server 是 Streamable HTTP 模式,则配置改成:
yaml复制spring:
ai:
mcp:
client:
sse:
servers:
stock:
url: http://localhost:8080/mcp
上面两种配置方式分别对应不同传输。初学者最容易犯的错,是觉得“我已经启动了 MCP Server 进程,客户端就能直接连”,实际上客户端需要重新拉起一个 Server 子进程或者直接连接 HTTP 地址,它们之间的连接方式是靠配置文件决定的。
4.2 用 ChatClient 暴露工具给大模型
在客户端工程里,我会注入 MCP 客户端提供的 ToolCallbackProvider,然后把它塞进 ChatClient。Spring AI Alibaba 的 ChatClient 用法和 Spring AI 一脉相承,最核心的代码就几行:
java复制@Service
public class StockAssistantService {
private final ChatClient chatClient;
public StockAssistantService(ChatClient.Builder builder, ToolCallbackProvider mcpToolProvider) {
this.chatClient = builder
.defaultTools(mcpToolProvider)
.build();
}
public String ask(String question) {
return chatClient.prompt()
.user(question)
.call()
.content();
}
}
这里的 mcpToolProvider 就是 Spring AI 在你配置了 MCP 客户端后自动注入的。它内部会启动客户端连接,拉取 MCP Server 的工具列表,并转换成框架通用的工具回调结构。当用户输入“帮我查一下贵州茅台最新价格”时,大模型会判断出需要调用 searchStock,把“贵州茅台”转成代码 sh600519,再调用 getStockRealtimeQuote。整个过程对用户完全透明。
我在实际测试中发现一个问题:模型有时只调用第一个工具 searchStock,拿到代码后就直接停止,不继续调用 getStockRealtimeQuote。后来我检查 Prompt 才发现,是工具描述不够明确。我把 getStockRealtimeQuote 的描述改成“必须配合searchStock调用,当用户需要价格、涨跌幅等数据时,在获取股票代码后立即调用本工具”,问题就没再出现。工具描述里适当加入“必须”这类指令词,对模型的行为引导有奇效。
4.3 多轮实战效果与参数调优
用这个客户端,我测试了几个典型 Prompt:
- “查一下茅台的最新价和涨跌幅。” 模型自动完成中文名到代码的映射,然后调行情接口。
- “五粮液和茅台今天哪个涨得多?” 模型会先分别搜索两只股票代码,再各调一次实时行情工具,最后自己比较涨跌幅并给出结论。
- “我想买点股票,帮我看看腾讯控股的成交额。” 模型能理解“腾讯控股”是港股,调用搜索工具映射到
hk00700,再返回行情。
第三类测试暴露了一个问题:中文名称和企业主体识别是搜索工具里最容易出错的环节。我建议在 searchStock 方法里维护一个“中文名到多个可能代码”的映射表,把 腾讯控股、腾讯、00700、hk00700 都映射到同一个代码。这样模型的容错率会明显提升。
如果把工具返回结果直接给模型,输出中可能夹带一堆 JSON 片段。我建议大家把工具方法返回的结构固定为一个 StockQuote 对象,内部字段名用中文别名注解输出,比如 "最新价": 1700.00。模型读到的字段名越接近人类语言,回答的质量越高。这一点是我在实战中对比明显才确认的。
5. 本地启动与接入的常见问题排查实录
5.1 报错:McpServer 的类或方法找不到
这几乎是新手最频繁的问题。原因基本可以锁定在 Spring AI 版本和 spring-ai-alibaba 版本不一致上。Spring AI 目前还处于快速迭代期,不同里程碑版本之间的 API 差异很大。解决思路是把所有 Spring AI 相关的依赖版本统一到一个版本,并且以 spring-ai-bom 的方式管理版本。Spring AI Alibaba 的版本最好也参考它的官方文档选配套版本。
千万不要把一个来自博客的 M4 版本和一个来自社区代码的 M6 版本混在一起。我在训练营中给学员统一的版本组合是:Spring Boot 3.3.4 + Spring AI 1.0.0-M6 + Spring AI Alibaba 1.0.0.1。这套组合在实际测试中运行稳定,工具注册、客户端调用、流式响应都能正常工作。
5.2 工具注册成功但模型始终不调用
我在第 4 节提到过工具描述的问题,这里再补充一个容易忽视的点:MCP Server 的工具名字不要用大写驼峰,尽量用小写加下划线或简单驼峰。某些模型的内部指令对工具名风格隐含有偏好,过长的名字也容易被截断。更关键的是,工具描述里一定要包含用户问题中可能出现的同义词。比如用户说“股价”、“行情”、“价格”,你的描述里就要包含“价格、涨跌幅、行情”这些词。
如果你的工具是 searchStock,描述里全是“代码搜索”,那模型在接收到“帮我查下茅台股价”时,可能不知道要用这个工具去先把“茅台”翻译成代码。把描述写成“搜索股票代码,支持股票中文名、拼音缩写、代码模糊查询,例如‘贵州茅台’、‘gzm’、‘600519’”,模型调用的成功率会高得多。
5.3 行情接口偶发超时或者返回空值
新浪和腾讯的免费接口在高峰期偶尔会延迟或者干脆返回空字符串。我在工具方法里加了一个简单的重试机制:如果第一次返回为空,等待 200 毫秒重试一次,最多三次。同时加了一层本地缓存,同一个股票代码在 10 秒内的重复查询直接返回缓存,避免频繁请求被远端限制。
这里要注意:缓存虽然能解决一部分限流问题,但行情数据的实时性会被牺牲。10 秒缓存对“查一下最新价”这类场景完全够用,对高频量化场景就不合适了。训练营学员自己演示时,还可以把缓存时间调成 30 秒,体验上区别不大,接口压力却小很多。
5.4 模型还是有可能瞎编行情数据
即使 MCP 工具已经被调用,我也遇到过模型把工具返回的数值念错或者自己补充一段不存在的数据的情况。这和大模型的生成机制有关,它并不擅长精确复述数字。解决办法是在 Prompt 里强化约束:“所有行情数据必须来源于工具返回 JSON,禁止自行推断或补全”,同时在工具返回值里把重要字段用中文标签标记清楚。
我对接的模型里,通义千问在工具结果处理上表现不错,能够按照要求简洁复述数据。如果你换了别的模型,一定要先做一轮工具调用准确性测试,再开放给用户。测试方法就是我前面说的,用一组固定问题,逐个检查模型输出的数字和 MCP Server 返回的 JSON 字段是否一一对应。
5.5 关于“spring ai alibaba 停更了”的疑虑
每次训练营里总有人问这个问题。我的结论是,大家最好直接去 Maven 中央仓库翻一下 com.alibaba.cloud.ai 的公开记录,看最近几个月的发布时间和更新内容,比任何网上的传言都靠谱。Spring AI Alibaba 的定位是让 Spring AI 生态更好地连接国内模型和云服务,MCP 这类基础设施能力本来也是 Spring AI 生态在做,Alibaba 分支持续同步并增强它,这件事本身就能说明项目是活着的。
当然,任何一个快速发展的开源项目在版本兼容性上都会有些颠簸,这不代表项目停更。真正要做决策的人,应该把关注点放在“它能不能解决我当前的问题”上。如果你想做一个调用通义千问、又需要自定义工具能力的应用,Spring AI Alibaba 目前是 Java 生态里最顺的一条路。
6. 项目扩展与训练营实操总结
6.1 从单机到远程:把 stdio 换成 HTTP 后发生了什么
我在训练营里把项目部署到一台小服务器时,第一时间就把传输方式换成了 Streamable HTTP。这一步的直观变化是,本地 java -jar 启动的进程变成了一个真正可被远程访问的服务,客户端只要填写服务器的 URL 就能直接连接 MCP Server。多客户端同时连接时,HTTP 版本还自动解决了并发问题,不需要额外做进程管理。
要注意的是,MCP HTTP 传输需要服务端和客户端的 Spring AI 版本保持一致,否则握手协议可能对不上。我在升级 HTTP 传输时遇到过客户端提示 unknown protocol version,排查半天才发现服务器用的 Spring AI 版本比客户端旧了一个里程碑。升级到相同版本后问题消失。
6.2 再补充一个实用工具:自写的本地启动脚本
每次用 npx @modelcontextprotocol/inspector 启动调试实在太累,我在项目根目录放了一个 start-local.sh,内容是把 Maven 打包、Java 启动、Inspector 启动串成一条命令。这样团队新成员拉下代码后,一行命令就能看到 MCP Server 的工具列表。本地启动 MCP Server 教程通常都比较繁琐,但通过脚本化可以让新人十分钟内跑通。
脚本核心部分就是先 mvn -DskipTests package,再启动 jar,等 2 秒后再 npx 连接。注意 Windows 用户需要用对应的 .bat 版本,路径分隔符也是常见坑。这个脚本看起来简单,却实打实提升了训练营的学习效率,我把完整脚本放在项目仓库的根目录,方便大家直接使用。
6.3 我对这套方案的真实评价
从第一次听课的学员反馈来看,最让我满意的不是工具本身跑通,而是大家通过这个项目真正理解了“MCP 是连接模型和工具的中间层”。很多人之前一直以为 MCP 有大模型那么复杂,亲手搭完才发现它不过是一个标准协议盒子,盒子里面装着你熟悉的普通 Java 方法。把注意力放在工具设计和数据质量上,MCP 反而不太容易出错。
最后分享一个小技巧:如果未来想把这套股票 MCP Server 扩展成更专业的行情助手,建议把工具返回值从“字符串”改成“结构化对象”,并且把每个工具的结果通过 McpSchema.CallToolResult 里的结构化内容字段返回。这样在线调试时看调用记录会更清晰,也方便客户端做后续的数据分析。这个改动会多写一点点代码,但绝对值得。
