- Pure Java 21 MCP Server
Pure Java 21 MCP Server
Pure Java 21 MCP Server
This project is an implementation of a Model Context Protocol (MCP) server in pure Java 21, strictly adhering to the (conceptual) 2025-03-26 MCP specification. It is built from scratch without external MCP-specific SDKs.
Prerequisites
- Java 21 SDK: Ensure you have Java 21 (or later) installed and configured.
- Gson Library: This server uses the Gson library for JSON parsing and serialization. You will need to download the Gson JAR file.
- You can typically download it from Maven Central. Search for "Gson" or
com.google.code.gson:gson. Download the JAR (e.g.,gson-2.10.1.jaror a later version). - Place the downloaded Gson JAR (e.g.,
gson-2.10.1.jar) in a known location, for example, alibdirectory within this project (lib/gson-2.10.1.jar). The compilation and run commands below assume this location.
- You can typically download it from Maven Central. Search for "Gson" or
Project Structure
src/: Contains the Java source code.main/java/io/modelcontextprotocol/server/: Root package.jsonrpc/: Classes for JSON-RPC message structures, parsing, and error handling.messages/: Classes for MCP-specific message payloads (initialize, tool definitions, etc.).tools/: Implementation of tools (e.g.,EchoTool).transport/: Transport layer handling (e.g.,StdioTransport).McpServer.java: Core server logic.Main.java: Application entry point.
lib/: (Recommended) Create this directory to store the Gson JAR.mcp-server.log: Log file generated by the server during operation..gitignore: Specifies intentionally untracked files that Git should ignore.README.md: This file.
Compilation
-
Create Directories:
- Ensure you have a
libdirectory in the project root and place the Gson JAR file (e.g.,gson-2.10.1.jar) there. - Create a
bindirectory in the project root to store the compiled class files: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/
- Ensure you have a
-
Compile the Server: Open a terminal or command prompt in the project's root directory. Adjust
lib/gson-2.10.1.jarif you are using a different version or path for Gson.Nix (Linux/macOS):
javac -d bin -cp "lib/gson-2.10.1.jar:src/main/java" $(find src/main/java -name "*.java")Windows (Command Prompt):
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 ';' ")If the
$(powershell ...)command doesn't work directly incmd.exe, you might need to list the files manually or use a different approach: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(Ensure all package paths are included if manually listing files).
Running the Server
After successful compilation, run the server from the project's root directory:
Nix (Linux/macOS):
java -cp "bin:lib/gson-2.10.1.jar" io.modelcontextprotocol.server.Main
Windows (Command Prompt):
java -cp "bin;lib\gson-2.10.1.jar" io.modelcontextprotocol.server.Main
The server will start and listen for JSON-RPC messages on standard input (STDIO).
Implemented Features
- Transport: STDIO (Content-Length header framed messages).
- JSON-RPC: Version 2.0 message parsing and serialization.
- MCP Core:
initializerequest: Server responds with its capabilities.initializednotification: Client confirms initialization.shutdownrequest: Server acknowledges and prepares to exit.exitnotification: Server terminates.
- Tools:
- Basic "Tool" capability.
tool/callrequest for theechoTool.echoTool: A simple tool that echoes a message.- Input schema:
{ "type": "object", "properties": { "message": { "type": "string" } } } - Output schema:
{ "type": "object", "properties": { "response": { "type": "string" } } }
- Input schema:
- Logging: Server activity is logged to
mcp-server.log(FINE level and above) and to the console (INFO level and above).
Example Interaction (via STDIO)
Messages are framed with Content-Length and \r\n\r\n before the JSON body.
1. Client -> Server: initialize Request
Content-Length: 123
{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"processId":1234,"capabilities":{}}}
(Note: params content like processId and capabilities are illustrative for initialize but are currently ignored by this server.)
2. Server -> Client: initialize Response
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"}}}]}}}
(Actual Content-Length will vary based on exact formatting. The server calculates this.)
3. Client -> Server: initialized Notification
Content-Length: 40
{"jsonrpc":"2.0","method":"initialized"}
(No id for notifications. Server does not respond.)
4. Client -> Server: tool/call for echoTool
Content-Length: 107
{"jsonrpc":"2.0","id":2,"method":"tool/call","params":{"toolName":"echoTool","params":{"message":"Hello MCP!"}}}
5. Server -> Client: tool/result Response
Content-Length: 74
{"jsonrpc":"2.0","id":2,"result":{"response":"Echo: Hello MCP!"}}
6. Client -> Server: shutdown Request
Content-Length: 49
{"jsonrpc":"2.0","id":3,"method":"shutdown","params":{}}
7. Server -> Client: shutdown Response
Content-Length: 34
{"jsonrpc":"2.0","id":3,"result":null}
8. Client -> Server: exit Notification
Content-Length: 36
{"jsonrpc":"2.0","method":"exit","params":{}}
(Server then terminates. No response.)