MCP服务器库

一个轻量级、易于使用的Java MCP服务器实现库,支持AI代理功能。

  • by fujohnwang
  • Java
  • 本地部署
  • 1 星标
  • 更新于
在 GitHub 查看 fujohnwang/mcp4j

使用说明

MCP4j简介

MCP服务器示例。Java生态系统中的支持很糟糕,它们(spring ai和其他Java框架)带来了太多令人讨厌的东西。

事实上,用Java构建MCP服务器应该很容易

这就是为什么我给你这个 图书馆:

  • 它重量轻,没有不必要的依赖
  • 它易于使用
  • AI代理已经准备就绪

快速开始

Maven依赖关系

<dependency>
    <groupId>me.afoo</groupId>
    <artifactId>mcp4j</artifactId>
    <version>0.1.0-SNAPSHOT</version>
</dependency>

示例:创建一个简单的MCP服务器

import me.afoo.mcp4j.schema.JsonSchema;
import me.afoo.mcp4j.server.McpServer;
import me.afoo.mcp4j.tool.Tool;

import java.time.Duration;

public class ExampleServer {
    public static void main(String[] args) throws Exception {
        McpServer server = McpServer.builder()
            .host("127.0.0.1")
            .port(8080)
            .endpoint("/mcp")
            .sessionTimeout(Duration.ofMinutes(30))
            // Tool 1: Echo
            .tool(Tool.builder()
                .name("echo")
                .description("Echo back the input message")
                .inputSchema(JsonSchema.object()
                    .property("message", JsonSchema.string()
                        .description("Message to echo back")
                        .required())
                    .build())
                .handler(params -> params.get("message"))
                .build())
            // Tool 2: Add numbers
            .tool(Tool.builder()
                .name("add")
                .description("Add two numbers together")
                .inputSchema(JsonSchema.object()
                    .property("a", JsonSchema.number()
                        .description("First number")
                        .required())
                    .property("b", JsonSchema.number()
                        .description("Second number")
                        .required())
                    .build())
                .handler(params -> {
                    double a = ((Number) params.get("a")).doubleValue();
                    double b = ((Number) params.get("b")).doubleValue();
                    return a + b;
                })
                .build())
            // Tool 3: Get current time
            .tool(Tool.builder()
                .name("get_time")
                .description("Get current server time")
                .inputSchema(JsonSchema.object()
                    .property("format", JsonSchema.string()
                        .description("Time format: iso8601 or unix")
                        .enumValues("iso8601", "unix")
                        .defaultValue("iso8601"))
                    .build())
                .handler(params -> {
                    String format = (String) params.getOrDefault("format", "iso8601");
                    if ("unix".equals(format)) {
                        return System.currentTimeMillis();
                    }
                    return java.time.Instant.now().toString();
                })
                .build())
            .build();

        server.start();
        System.out.println("MCP Server started at: " + server.getAddress());
        
        // Graceful shutdown
        Runtime.getRuntime().addShutdownHook(new Thread(server::stop));
        Thread.currentThread().join();
    }
}

运行示例

mvn exec:java -Dexec.mainClass="me.afoo.mcp4j.example.ExampleServer"

卷曲测试

# Initialize
curl -X POST http://127.0.0.1:8080/mcp \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "initialize",
    "params": {
      "protocolVersion": "2025-03-26",
      "capabilities": {},
      "clientInfo": {"name": "test-client", "version": "1.0.0"}
    }
  }'

# List tools
curl -X POST http://127.0.0.1:8080/mcp \
  -H "Content-Type: application/json" \
  -H "Mcp-Session-Id: <session-id-from-initialize>" \
  -d '{
    "jsonrpc": "2.0",
    "id": 2,
    "method": "tools/list",
    "params": {}
  }'

# Call a tool
curl -X POST http://127.0.0.1:8080/mcp \
  -H "Content-Type: application/json" \
  -H "Mcp-Session-Id: <session-id-from-initialize>" \
  -d '{
    "jsonrpc": "2.0",
    "id": 3,
    "method": "tools/call",
    "params": {
      "name": "add",
      "arguments": {"a": 10, "b": 32}
    }
  }'