mcp-server-example

aliaksandr-haurylau-godel/mcp-server-example

3.2

If you are the rightful owner of mcp-server-example and would like to certify it and/or have it hosted online, please leave a comment on the right or send an email to henry@mcphub.com.

This project is a pure Java 21 implementation of a Model Context Protocol (MCP) server, adhering to the 2025-03-26 MCP specification.

Tools
1
Resources
0
Prompts
0

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.jar or a later version).
    • Place the downloaded Gson JAR (e.g., gson-2.10.1.jar) in a known location, for example, a lib directory within this project (lib/gson-2.10.1.jar). The compilation and run commands below assume this location.

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

  1. Create Directories:

    • Ensure you have a lib directory in the project root and place the Gson JAR file (e.g., gson-2.10.1.jar) there.
    • Create a bin directory 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/
      
  2. Compile the Server: Open a terminal or command prompt in the project's root directory. Adjust lib/gson-2.10.1.jar if 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 in cmd.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:
    • initialize request: Server responds with its capabilities.
    • initialized notification: Client confirms initialization.
    • shutdown request: Server acknowledges and prepares to exit.
    • exit notification: Server terminates.
  • Tools:
    • Basic "Tool" capability.
    • tool/call request for the echoTool.
    • echoTool: A simple tool that echoes a message.
      • Input schema: { "type": "object", "properties": { "message": { "type": "string" } } }
      • Output schema: { "type": "object", "properties": { "response": { "type": "string" } } }
  • 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.)