spring-ai mcp-server(ssh工具)

摘要:本文主要介绍用spring-ai开发一个sshmcp工具,公司研发人员可以用这个mcp处理服务器的问题和自动化更新。

实操代码

pom.xml

xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.5.9</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>sp3-mcp</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>sp3-mcp</name>
    <description>sp3-mcp</description>
    <url/>
    <licenses>
        <license/>
    </licenses>
    <developers>
        <developer/>
    </developers>
    <scm>
        <connection/>
        <developerConnection/>
        <tag/>
        <url/>
    </scm>
    <properties>
        <java.version>21</java.version>
        <maven.compiler.source>21</maven.compiler.source>
        <maven.compiler.target>21</maven.compiler.target>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.ai</groupId>
            <artifactId>spring-ai-starter-mcp-server-webmvc</artifactId>
        </dependency>
        
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.33</version>
        </dependency>

        <dependency>
            <groupId>com.jcraft</groupId>
            <artifactId>jsch</artifactId>
            <version>0.1.55</version>
        </dependency>
        
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.ai</groupId>
                <artifactId>spring-ai-bom</artifactId>
                <version>1.1.2</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

</project>

SshToolService

less 复制代码
@Service
public class SshToolService {

    @McpTool(description = "执行MySQL查询语句(SELECT)")
    public String executeSshCommand(
            @McpToolParam(description = "远程服务器 IP") String host,
            @McpToolParam(description = "SSH 端口,通常是 22") Integer port,
            @McpToolParam(description = "用户名") String username,
            @McpToolParam(description = "登录密码") String password,
            @McpToolParam(description = "要执行的命令") String command) {

        Session session = null;
        ChannelExec channel = null;

        try {
            JSch jsch = new JSch();

            // 1. 获取 Session
            session = jsch.getSession(username, host, port != null ? port : 22);

            // 2. 设置密码 (关键修改点)
            session.setPassword(password);

            // 3. 关闭 HostKey 检查 (避免 UnknownHostKey 异常,避免交互式确认)
            session.setConfig("StrictHostKeyChecking", "no");

            // 可选:设置超时时间 (毫秒)
            session.connect(10000);

            // 4. 打开执行通道
            channel = (ChannelExec) session.openChannel("exec");
            channel.setCommand(command);
            channel.setInputStream(null);

            // 5. 获取输入流(读取命令结果)和错误流
            InputStream in = channel.getInputStream();
            InputStream err = channel.getErrStream();

            channel.connect();

            // 6. 读取输出数据
            StringBuilder outputBuffer = new StringBuilder();
            byte[] tmp = new byte[1024];
            while (true) {
                while (in.available() > 0) {
                    int i = in.read(tmp, 0, 1024);
                    if (i < 0) break;
                    outputBuffer.append(new String(tmp, 0, i, StandardCharsets.UTF_8));
                }
                // 同时也读取错误流,防止缓冲区满导致挂起
                while (err.available() > 0) {
                    int i = err.read(tmp, 0, 1024);
                    if (i < 0) break;
                    outputBuffer.append("STDERR: ").append(new String(tmp, 0, i, StandardCharsets.UTF_8));
                }

                if (channel.isClosed()) {
                    if (in.available() > 0) continue;
                    break;
                }
                try { Thread.sleep(100); } catch (Exception ee) {}
            }

            return outputBuffer.toString();

        } catch (Exception e) {
            e.printStackTrace();
            return "SSH 连接或执行失败: " + e.getMessage();
        } finally {
            if (channel != null) channel.disconnect();
            if (session != null) session.disconnect();
        }
    }
}

application.properties

ini 复制代码
# spring.main.web-application-type=none

# NOTE: You must disable the banner and the console logging 
# to allow the STDIO transport to work !!!
spring.main.banner-mode=off
# logging.pattern.console=

# spring.ai.mcp.server.stdio=false

spring.ai.mcp.server.name=mcp-weather-server
spring.ai.mcp.server.request-timeout=1h

spring.ai.mcp.server.protocol=sse

logging.file.name=./mcp-weather-server/target/server.log

客户端配置

mcp_config.json

json 复制代码
{
  "mcpServers": {
    "天气服务": {
      "disabledTools": [],
      "serverUrl": "http://localhost:8080/sse"
    }
  }
}
相关推荐
前端付豪3 小时前
AI 数学辅导老师项目构想和初始化
前端·后端·python
七牛云行业应用3 小时前
保姆级 OpenClaw 避坑指南:手把手教你看日志修 Bug,顺畅连通各大 AI 模型
人工智能·后端·node.js
程序员爱钓鱼3 小时前
Go并发控制核心:context 包完整技术解析
后端·google·go
树獭叔叔3 小时前
OpenClaw Plugins 与 Hooks 系统:让 AI 助手无限可能
后端·aigc·openai
FE_winter3 小时前
OpenClaw Skills 进阶实战:前端开发者的 AI 技能库搭建指南
前端·后端·程序员
Java编程爱好者4 小时前
用Spring的ApplicationEventPublisher进行事件发布和监听
后端
Mintopia4 小时前
OpenClaw在日常开发中的应用实践与全场景解析
人工智能·openai·ai编程
Java编程爱好者4 小时前
MySQL索引优化实战:从原理到调优
后端
梁大虎4 小时前
Electrobun 开发必看:CEF 依赖下载失败?手动解压一招搞定!
前端·javascript·后端