MCP服务器

一个基于Java 21的Model Context Protocol (MCP)服务器实现,支持JSON-RPC 2.0消息解析和序列化,适用于工具调用和消息传递场景。

  • by aliaksandr-haurylau-godel
  • Java
  • 本地部署
  • 更新于
在 GitHub 查看 aliaksandr-haurylau-godel/mcp-server-example

使用说明

纯Java 21 MCP服务器

该项目是纯Java 21中模型上下文协议(MCP)服务器的实现,严格遵守(概念性)2025-03-26 MCP规范。它是从头开始构建的,没有外部MCP特定的SDK。

先决条件

  • Java 21软件开发工具包: 确保您已安装并配置了Java 21(或更高版本)。
  • Gson图书馆: 此服务器使用Gson库进行JSON解析和序列化。您需要下载Gson JAR文件。
    • 您通常可以从Maven Central下载它。搜索“Gson”或 com.google.code.gson:gson下载JAR(例如。, gson-2.10.1.jar 或更高版本)。
    • 将下载的Gson JAR(例如。, gson-2.10.1.jar)在已知位置,例如 lib 此项目中的目录(lib/gson-2.10.1.jar).下面的编译和运行命令假定位于此位置。

项目结构

  • src/:包含Java源代码。
    • main/java/io/modelcontextprotocol/server/:根包。
      • jsonrpc/:JSON-RPC消息结构、解析和错误处理的类。
      • messages/:MCP特定消息有效载荷的类(初始化、工具定义等)。
      • tools/:工具的实施(例如。, EchoTool).
      • transport/:传输层处理(例如。, StdioTransport).
      • McpServer.java:核心服务器逻辑。
      • Main.java:应用程序入口点。
  • lib/:(推荐)创建此目录以存储Gson JAR。
  • mcp-server.log:服务器在操作过程中生成的日志文件。
  • .gitignore:指定Git应忽略的有意未跟踪的文件。
  • README.md:这个文件。

编译

  1. 创建目录:

    • 确保你有一个 lib 将Gson JAR文件(例如。, gson-2.10.1.jar)在那里。
    • 创建一个 bin 项目根目录中存储编译类文件的目录:
      mkdir lib
      mkdir bin
      # Download Gson JAR and place it in lib/
      # For example: wget https://repo1.maven.org/maven2/com/google/code/gson/gson/2.10.1/gson-2.10.1.jar -P lib/
      
  2. 编译服务器: 在项目的根目录中打开终端或命令提示符。 调整 lib/gson-2.10.1.jar 如果您正在为Gson使用不同的版本或路径。

    Nix(Linux/macOS):

    javac -d bin -cp "lib/gson-2.10.1.jar:src/main/java" $(find src/main/java -name "*.java")
    

    Windows(命令提示符):

    javac -d bin -cp "lib\gson-2.10.1.jar;src\main\java" $(powershell -Command "(Get-ChildItem -Recurse -Filter *.java src\main\java | Select-Object -ExpandProperty FullName) -join ';' ")
    

    如果 $(powershell ...) 命令不能直接在中工作 cmd.exe,您可能需要手动列出文件或使用其他方法:

    javac -d bin -cp "lib\gson-2.10.1.jar;src\main\java" src\main\java\io\modelcontextprotocol\server\*.java src\main\java\io\modelcontextprotocol\server\jsonrpc\*.java src\main\java\io\modelcontextprotocol\server\messages\*.java src\main\java\io\modelcontextprotocol\server	ools\*.java src\main\java\io\modelcontextprotocol\server	ransport\*.java
    

    (如果手动列出文件,请确保包含所有包路径)。

运行服务器

编译成功后,从项目的根目录运行服务器:

Nix(Linux/macOS):

java -cp "bin:lib/gson-2.10.1.jar" io.modelcontextprotocol.server.Main

Windows(命令提示符):

java -cp "bin;lib\gson-2.10.1.jar" io.modelcontextprotocol.server.Main

服务器将启动并监听标准输入(STDIO)上的JSON-RPC消息。

已实现的功能

  • 运输: STDIO(Content-Length头帧消息)。
  • JSON-RPC: 2.0版本消息解析和序列化。
  • MCP核心:
    • initialize 请求:服务器以其功能进行响应。
    • initialized 通知:客户端确认初始化。
    • shutdown 请求:服务器确认并准备退出。
    • exit 通知:服务器终止。
  • 工具:
    • 基本的“工具”能力。
    • tool/call 请求 echoTool.
    • echoTool:一个回应信息的简单工具。
      • 输入架构: { "type": "object", "properties": { "message": { "type": "string" } } }
      • 输出架构: { "type": "object", "properties": { "response": { "type": "string" } } }
  • 登录中: 服务器活动已记录到 mcp-server.log (精细级别及以上)和控制台(信息级别及以上的)。

交互示例(通过STDIO)

消息被框起来 Content-Length 和 \r\n\r\n 在JSON正文之前。

1.客户端->服务器: initialize 请求

Content-Length: 123

{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"processId":1234,"capabilities":{}}}

(注: params 内容类似 processId 和 capabilities 用于说明 initialize 但当前被该服务器忽略。)

2.服务器->客户端: initialize 响应

Content-Length: 297

{"jsonrpc":"2.0","id":1,"result":{"capabilities":{"tools":[{"name":"echoTool","description":"A simple tool that takes a 'message' string and returns it prefixed with 'Echo: '.","inputSchema":{"type":"object","properties":{"message":"string"}},"outputSchema":{"type":"object","properties":{"response":"string"}}}]}}}

(实际内容长度将根据确切的格式而有所不同。服务器会对此进行计算。)

3.客户端->服务器: initialized 通知

Content-Length: 40

{"jsonrpc":"2.0","method":"initialized"}

(没有 id 用于通知。服务器没有响应。)

4.客户端->服务器: tool/call 为了 echoTool

Content-Length: 107

{"jsonrpc":"2.0","id":2,"method":"tool/call","params":{"toolName":"echoTool","params":{"message":"Hello MCP!"}}}

5.服务器->客户端: tool/result 响应

Content-Length: 74

{"jsonrpc":"2.0","id":2,"result":{"response":"Echo: Hello MCP!"}}

6.客户端->服务器: shutdown 请求

Content-Length: 49

{"jsonrpc":"2.0","id":3,"method":"shutdown","params":{}}

7.服务器->客户端: shutdown 响应

Content-Length: 34

{"jsonrpc":"2.0","id":3,"result":null}

8.客户端->服务器: exit 通知

Content-Length: 36

{"jsonrpc":"2.0","method":"exit","params":{}}

(服务器随后终止。没有响应。)