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;
    }
}
相关推荐
GIS阵地1 小时前
QgsSingleBandPseudoColorRenderer 完整详解(QGIS 3.40.13 C++)
开发语言·前端·c++·qt·qgis
刘较瘦_1 小时前
AI 开发中的 Git Submodule 父子仓库模式:前后端分仓管理与协作实践
前端·github
牧艺2 小时前
cos-design WeatherBackground:用 Canvas 做一个「会变天」的背景引擎
前端·canvas·视觉设计
OpenTiny社区2 小时前
深度解析 LSP 如何为 AI 装上“眼睛”
前端·ai编程
布列瑟农的星空2 小时前
流程类SVG画布的通用开发范式
前端
fsssb2 小时前
Chromium 源码学习笔记(七):那些跨进程的调用,底下都是同一个东西——Mojo
前端
MichaelJohn3 小时前
从零星白屏到“启发式缓存”,记录一次刚接手屎山的惊险排查
前端
程序员黑豆3 小时前
鸿蒙应用开发:6种图片加载方式详解
前端·华为·harmonyos
半个落月3 小时前
用 React 搭一个 WebGPU 模型加载页:从状态驱动到可复用进度条
前端·react.js
雪隐3 小时前
个人电脑玩AI-13让5060 Ti给你打工——我用 0.9B 小模型终结了"谁来记会议纪要"这个世纪难题
前端·人工智能·后端