SpringAI1.0的MCPServer自动暴露Tool

java 复制代码
@Configuration
public class ToolAutoRegistrar {

    @Autowired
    private ListableBeanFactory beanFactory;

    @Bean
    public ToolCallbackProvider toolCallbackProvider() {
        List<Object> toolBeans = beanFactory.getBeansWithAnnotation(Service.class)
                .values().stream()
                .filter(bean -> Arrays.stream(bean.getClass().getMethods())
                        .anyMatch(method -> method.isAnnotationPresent(Tool.class)))
                .collect(Collectors.toList());

        return MethodToolCallbackProvider.builder()
                .toolObjects(toolBeans.toArray())
                .build();
    }
}

这段代码会自动查找所有 @Service Bean 中包含 @Tool 注解的方法,然后注册进去。

更加健壮的代码

java 复制代码
package com.example.mcp.config;

import org.springframework.aop.framework.AopProxyUtils;
import org.springframework.beans.factory.ListableBeanFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.ai.tool.ToolCallbackProvider;
import org.springframework.ai.tool.MethodToolCallbackProvider;
import org.springframework.ai.tool.Tool;

import java.lang.reflect.Method;
import java.util.List;
import java.util.stream.Collectors;

@Configuration
public class ToolAutoRegistrar {

    @Bean
    public ToolCallbackProvider toolCallbackProvider(ListableBeanFactory beanFactory) {
        List<Object> toolBeans = beanFactory.getBeansOfType(Object.class)
                .values().stream()
                .filter(bean -> hasToolAnnotatedMethod(bean))
                .collect(Collectors.toList());

        return MethodToolCallbackProvider.builder()
                .toolObjects(toolBeans.toArray())
                .build();
    }

    private boolean hasToolAnnotatedMethod(Object bean) {
        Class<?> targetClass = AopProxyUtils.ultimateTargetClass(bean);
        for (Method method : targetClass.getDeclaredMethods()) {
            if (method.isAnnotationPresent(Tool.class)) {
                return true;
            }
        }
        return false;
    }
}
相关推荐
鬼手点金5 小时前
nanoGPT/nanochat 能做出 DeepSeek/Qwen 这样的大模型吗?
服务器·前端·javascript·bug·openclaw
蛋蛋的就会顺顺的5 小时前
hot100 p0——栈,贪心算法,动态规划
java·前端·javascript·算法·leetcode·力扣
程序员Sunday5 小时前
TypeScript 的 any、unknown、never 有什么区别?
前端·面试·typescript
朱涛的自习室5 小时前
70 美金的 Beyond Compare,我让 Gemini 4 和 DeepSeek 造个开源免费版(Day 2)
android·前端·人工智能
码艺-Alimjan6 小时前
Tauri 源码备份 · 打包 & 解压 总结,源码收集之路
前端·javascript·vue.js
小马不起床6 小时前
零基础玩转 FastAPI_11:前端后台管理页面
前端·状态模式·fastapi
子非鱼a7 小时前
【文件上传】一个普普通通的edu16
前端
美狐美颜SDK开放平台8 小时前
直播APP如何实现美白滤镜功能?视频美颜SDK技术开发方案详解
前端·数据库·人工智能·音视频·美颜sdk·直播美颜sdk·视频美颜sdk
pride.li9 小时前
第03章 Python 教程-基础语法:注释与变量
服务器·前端·后端·python·算法·计算机视觉
屏什么录9 小时前
电脑如何录屏幕视频和声音?从工具到代码,7 种方案帮你彻底搞定
前端·音视频开发