返回市场
vertx-mcp服务器

vertx-mcp服务器

作者:Kinotic-Foundation7 星标更新:2025-08-13

项目介绍

Vert.x MCP 服务器

基于 Vert.x 的传输实现,用于 Model Context Protocol (MCP) Java SDK。该项目提供了一个轻量级、非阻塞的传输层,用于将 MCP 服务器与 Vert.x 应用程序集成。

概述

Vert.x MCP 服务器提供了以下功能:

  • Vert.x 传输:一个 VertxMcpTransport 接口,提供了一个 Vert.x 路由器,以便将其集成到您的 Vert.x 应用程序中。
  • SSE 传输:用于实时双向通信的 Server-Sent Events (SSE) 实现。
  • 可流式传输的 HTTP 传输:新的 MCP 2025-06-18 可流式传输的 HTTP 传输实现。
  • Verticle 支持:一个可以立即使用的 McpVerticle,便于部署。
  • 非阻塞:基于 Vert.x 的高性能事件驱动架构。
  • 会话管理:自动处理客户端会话,并支持优雅关闭。

⚠️ 实验状态

此项目目前处于实验阶段,尚未在生产环境中进行全面测试。

  • 实现遵循 MCP 规范,但可能包含错误或不完整的功能。
  • 随着项目的成熟,API 可能会发生变化。
  • 性能特性尚未经过彻底的基准测试。
  • 如遇任何错误、问题或意外行为,请报告。
  • 欢迎贡献和反馈以帮助改进项目。

安装

Maven

<dependency>
    <groupId>org.kinotic</groupId>
    <artifactId>vertx-mcp</artifactId>
    <version>4.5.1</version>
</dependency>

Gradle

dependencies {
    implementation 'org.kinotic:vertx-mcp:4.5.1'
}

版本兼容性

  • 4.5.x 版本:兼容 Vert.x 4.5.x。
  • 5.0.x 版本:将兼容 Vert.x 5.x(尚未支持)。

快速开始

1. 创建 MCP 服务器

首先,使用官方 Java MCP SDK 创建您的 MCP 服务器:

import io.modelcontextprotocol.server.McpServer;
import io.modelcontextprotocol.server.McpServerFeatures;
import io.modelcontextprotocol.spec.McpSchema;
import io.modelcontextprotocol.spec.ServerCapabilities;
import java.util.List;
import reactor.core.publisher.Mono;

// 创建一个简单的计算器工具
var calculatorTool = McpServerFeatures.AsyncToolSpecification.builder()
    .tool(McpSchema.Tool.builder()
        .name("calculator")
        .description("基本计算器")
        .inputSchema("""
            {
              "type": "object",
              "properties": {
                "operation": {"type": "string", "enum": ["add", "subtract", "multiply", "divide"]},
                "a": {"type": "number"},
                "b": {"type": "number"}
              },
              "required": ["operation", "a", "b"]
            }
            """)
        .build())
    .callHandler((exchange, toolReq) -> {
        String operation = (String) toolReq.arguments().get("operation");
        double a = ((Number) toolReq.arguments().get("a")).doubleValue();
        double b = ((Number) toolReq.arguments().get("b")).doubleValue();
        
        double result = switch (operation) {
            case "add" -> a + b;
            case "subtract" -> a - b;
            case "multiply" -> a * b;
            case "divide" -> a / b;
            default -> throw new IllegalArgumentException("未知操作:" + operation);
        };
        
        return Mono.just(McpSchema.CallToolResult.builder()
            .textContent(List.of(String.valueOf(result)))
            .isError(false)
            .build());
    })
    .build();

// 创建 MCP 服务器规范(暂不调用 .build())
var mcpServerSpec = McpServer.async(transportProvider)
    .serverInfo("calculator-server", "1.0.0")
    .capabilities(ServerCapabilities.builder()
        .tools(true)
        .build())
    .tools(calculatorTool);

2. 创建 Vert.x 传输

选项 A:使用旧版 HTTP+SSE 传输

import io.vertx.ext.mcp.transport.VertxMcpSseServerTransportProvider;
import com.fasterxml.jackson.databind.ObjectMapper;

// 创建传输
var transport = VertxMcpSseServerTransportProvider.builder()
    .baseUrl("http://localhost:8080")
    .messageEndpoint("/mcp/message")
    .sseEndpoint("/mcp/sse")
    .keepAliveInterval(Duration.ofSeconds(30))
    .objectMapper(new ObjectMapper())
    .vertx(vertx)
    .build();

选项 B:使用新版可流式传输的 HTTP 传输

import io.vertx.ext.mcp.transport.VertxMcpStreamableServerTransportProvider;
import com.fasterxml.jackson.databind.ObjectMapper;

// 创建可流式传输的 HTTP 传输
var transport = VertxMcpStreamableServerTransportProvider.builder()
    .objectMapper(new ObjectMapper())
    .mcpEndpoint("/mcp")
    .disallowDelete(false)
    .vertx(vertx)
    .build();

3. 与您的 Vert.x 应用程序集成

使用提供的 Verticle 进行轻松集成:

import io.vertx.ext.mcp.McpVerticle;

// 部署 MCP verticle(传递传输和服务器规范)
vertx.deployVerticle(new McpVerticle(8080, transport, mcpServerSpec), ar -> {
    if (ar.succeeded()) {
        System.out.println("MCP Verticle 部署成功");
    } else {
        System.err.println("无法部署 MCP Verticle:" + ar.cause());
    }
});

4. 完整示例

示例 A:旧版 HTTP+SSE 传输

这是一个使用旧版 HTTP+SSE 传输的完整工作示例:

import io.vertx.core.Vertx;
import io.vertx.ext.mcp.McpVerticle;
import io.vertx.ext.mcp.transport.VertxMcpSseServerTransportProvider;
import io.modelcontextprotocol.server.McpServer;
import io.modelcontextprotocol.server.McpServerFeatures;
import io.modelcontextprotocol.spec.McpSchema;
import io.modelcontextprotocol.spec.ServerCapabilities;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.time.Duration;
import java.util.List;
import reactor.core.publisher.Mono;

public class LegacyMcpServerExample {
    public static void main(String[] args) {
        Vertx vertx = Vertx.vertx();
        
        // 创建带有简单计算器工具的 MCP 服务器
        var calculatorTool = McpServerFeatures.AsyncToolSpecification.builder()
            .tool(McpSchema.Tool.builder()
                .name("calculator")
                .description("基本计算器")
                .inputSchema("""
                    {
                      "type": "object",
                      "properties": {
                        "operation": {"type": "string", "enum": ["add", "subtract", "multiply", "divide"]},
                        "a": {"type": "number"},
                        "b": {"type": "number"}
                      },
                      "required": ["operation", "a", "b"]
                    }
                    """)
                .build())
            .callHandler((exchange, toolReq) -> {
                String operation = (String) toolReq.arguments().get("operation");
                double a = ((Number) toolReq.arguments().get("a")).doubleValue();
                double b = ((Number) toolReq.arguments().get("b")).doubleValue();
                
                double result = switch (operation) {
                    case "add" -> a + b;
                    case "subtract" -> a - b;
                    case "multiply" -> a * b;
                    case "divide" -> a / b;
                    default -> throw new IllegalArgumentException("未知操作:" + operation);
                };
                
                return Mono.just(McpSchema.CallToolResult.builder()
                    .textContent(List.of(String.valueOf(result)))
                    .isError(false)
                    .build());
            })
            .build();

        // 创建旧版 HTTP+SSE 传输
        var transport = VertxMcpSseServerTransportProvider.builder()
            .baseUrl("http://localhost:8080")
            .messageEndpoint("/mcp/message")
            .sseEndpoint("/mcp/sse")
            .keepAliveInterval(Duration.ofSeconds(30))
            .objectMapper(new ObjectMapper())
            .vertx(vertx)
            .build();

        // 创建 MCP 服务器规范(暂不调用 .build())
        var mcpServerSpec = McpServer.async(transport)
            .serverInfo("calculator-server", "1.0.0")
            .capabilities(ServerCapabilities.builder()
                .tools(true)
                .build())
            .tools(calculatorTool);

        // 部署 MCP verticle(传递传输和服务器规范)
        vertx.deployVerticle(new McpVerticle(8080, transport, mcpServerSpec), ar -> {
            if (ar.succeeded()) {
                System.out.println("MCP 服务器已在 8080 端口启动");
                System.out.println("SSE 端点:http://localhost:8080/mcp/sse");
                System.out.println("消息端点:http://localhost:8080/mcp/message");
            } else {
                System.err.println("无法启动 MCP 服务器:" + ar.cause());
            }
        });
    }
}

示例 B:新版可流式传输的 HTTP 传输

这是一个使用新版 MCP 2025-06-18 可流式传输的 HTTP 传输的完整工作示例:

import io.vertx.core.Vertx;
import io.vertx.ext.mcp.McpVerticle;
import io.vertx.ext.mcp.transport.VertxMcpStreamableServerTransportProvider;
import io.modelcontextprotocol.server.McpServer;
import io.modelcontextprotocol.server.McpServerFeatures;
import io.modelcontextprotocol.spec.McpSchema;
import io.modelcontextprotocol.spec.ServerCapabilities;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.time.Duration;
import java.util.List;
import reactor.core.publisher.Mono;

public class StreamableMcpServerExample {
    public static void main(String[] args) {
        Vertx vertx = Vertx.vertx();
        
        // 创建带有简单计算器工具的 MCP 服务器
        var calculatorTool = McpServerFeatures.AsyncToolSpecification.builder()
            .tool(McpSchema.Tool.builder()
                .name("calculator")
                .description("基本计算器")
                .inputSchema("""
                    {
                      "type": "object",
                      "properties": {
                        "operation": {"type": "string", "enum": ["add", "subtract", "multiply", "divide"]},
                        "a": {"type": "number"},
                        "b": {"type": "number"}
                      },
                      "required": ["operation", "a", "b"]
                    }
                    """)
                .build())
            .callHandler((exchange, toolReq) -> {
                String operation = (String) toolReq.arguments().get("operation");
                double a = ((Number) toolReq.arguments().get("a")).doubleValue();
                double b = ((Number) toolReq.arguments().get("b")).doubleValue();
                
                double result = switch (operation) {
                    case "add" -> a + b;
                    case "subtract" -> a - b;
                    case "multiply" -> a * b;
                    case "divide" -> a / b;
                    default -> throw new IllegalArgumentException("未知操作:" + operation);
                };
                
                return Mono.just(McpSchema.CallToolResult.builder()
                    .textContent(List.of(String.valueOf(result)))
                    .isError(false)
                    .build());
            })
            .build();

        // 创建可流式传输的 HTTP 传输
        var transport = VertxMcpStreamableServerTransportProvider.builder()
            .objectMapper(new ObjectMapper())
            .mcpEndpoint("/mcp")
            .disallowDelete(false)
            .vertx(vertx)
            .keepAliveInterval(Duration.ofSeconds(30))
            .build();

        // 创建 MCP 服务器规范(暂不调用 .build())
        var mcpServerSpec = McpServer.async(transport)
            .serverInfo("calculator-server", "1.0.0")
            .capabilities(ServerCapabilities.builder()
                .tools(true)
                .build())
            .tools(calculatorTool);

        // 部署 MCP verticle(传递传输和服务器规范)
        vertx.deployVerticle(new McpVerticle(8080, transport, mcpServerSpec), ar -> {
            if (ar.succeeded()) {
                System.out.println("MCP 服务器已在 8080 端口启动");
                System.out.println("可流式传输的 HTTP 端点:http://localhost:8080/mcp");
                System.out.println("支持:GET(SSE),POST(消息),DELETE(会话)");
            } else {
                System.err.println("无法启动 MCP 服务器:" + ar.cause());
            }
        });
    }
}

配置选项

旧版 HTTP+SSE 传输

VertxMcpSseServerTransportProvider 支持以下配置选项:

  • baseUrl:服务器的基础 URL(必需)
  • messageEndpoint:接收 JSON-RPC 消息的端点(默认:/message
  • sseEndpoint:SSE 连接的端点(默认:/sse
  • keepAliveInterval:保持连接的间隔时间(默认:30 秒)
  • objectMapper:Jackson ObjectMapper 用于 JSON 序列化
  • vertx:Vert.x 实例

可流式传输的 HTTP 传输

VertxMcpStreamableServerTransportProvider 支持以下配置选项:

  • objectMapper:Jackson ObjectMapper 用于 JSON 处理(必需)
  • mcpEndpoint:MCP 端点路径(默认:/mcp
  • disallowDelete:是否禁用会话删除(默认:false
  • vertx:Vert.x 实例(必需)
  • keepAliveInterval:保持连接的间隔时间(默认:30 秒)

架构

旧版 HTTP+SSE 传输

传输通过以下方式实现 MCP 协议:

  1. SSE 连接/sse):建立 Server-Sent Events 连接,用于服务器到客户端的通信。
  2. 消息端点/message):接收来自客户端的 JSON-RPC 消息。
  3. 会话管理:自动管理客户端会话并清理。
  4. 心跳:发送周期性的 ping 消息以防止连接超时。

新版可流式传输的 HTTP 传输

新的可流式传输的 HTTP 传输遵循 MCP 2025-06-18 规范:

  1. 单一端点/mcp):处理所有 HTTP 方法(GET、POST、DELETE)。
  2. 会话管理:使用 MCP SDK 会话管理,具有唯一的会话 ID。
  3. 连接恢复:支持通过 Last-Event-ID 头恢复中断的连接。
  4. 协议合规性:完全符合最新的 MCP 规范。

测试

您可以使用任何 MCP 客户端测试您的 MCP 服务器:

旧版传输

  • SSE 端点http://localhost:8080/mcp/sse 用于建立连接。
  • 消息端点http://localhost:8080/mcp/message?sessionId=<id> 用于发送请求。

新版传输

  • 单一端点http://localhost:8080/mcp 用于所有操作。
  • GET:建立 SSE 监听流。
  • POST:发送 JSON-RPC 消息。
  • DELETE:终止会话。

优雅关闭

传输支持优雅关闭:

// 优雅地关闭传输
transport.closeGracefully()
    .doOnSuccess(v -> System.out.println("传输已成功关闭"))
    .doOnError(e -> System.err.println("关闭传输时出错:" + e))
    .subscribe();

发展路线图

计划在未来版本中添加以下功能:

Vert.x 5 支持

支持 Vert.x 5.x 版本,包括:

  • 兼容 Vert.x 5.x API。
  • 更新的传输实现以适应 Vert.x 5。
  • 利用新 Vert.x 5 功能进行性能改进。

授权支持

实现 MCP 授权 功能,包括:

  • 符合 OAuth 2.1 的授权流程。
  • 动态客户端注册。
  • 访问令牌验证和受众绑定。
  • 支持安全令牌发行的资源参数。

贡献

欢迎贡献!请随时提交拉取请求或打开问题报告错误和功能请求。

许可证

本项目根据 Apache 许可证,版本 2.0 授权。