Among other things, Model Context Protocol (MCP) enables AI models to interact with external tools and services through a structured interface. Which allows models to defer control to actual software libraries and execute tasks with reproducibility, predictable performance, and security guarantees.
This blog post demonstrates creating an MCP server in Java that integrates the open-source chess engine Stockfish. We will use this MCP server to equip AI models with the state of the art ability to analyze chess positions and moves.
We chose Java because it's an enterprise-standard language widely adopted for large-scale applications. Its ecosystem is robust, mature, and continues to power thousands of enterprise solutions.
Stockfish Setup
Stockfish is a highly popular open source chess engine.
The MCP server implementation will consist of a Docker image with the Stockfish binary for chess analysis and a Quarkus application implementing the MCP protocol around the Stockfish binary.
You can check out the complete project on GitHub: https://github.com/shelajev/mcp-stockfish/tree/main
To implement the MCP server functionality with Quarkus, we need the quarkus-mcp-server-sse dependency, which you can install just like any other Quarkus extension using a Maven command:
./mvnw quarkus:add-extension -Dextensions="io.quarkiverse.mcp:quarkus-mcp-server-sse"
It will essentially add the necessary dependency section to the pom.xml
and in case of more complex extenstions can also add the build plugins, and change the configuration for everything to work out of the box.
<dependency>
<groupId>io.quarkiverse.mcp</groupId>
<artifactId>quarkus-mcp-server-sse</artifactId>
<version>1.2.0</version>
</dependency>
The tool implementation, marked with a @Tool
annotation will be automatically picked up by Quarkus and registered to be announced when the MCP requests start coming in.
@Singleton
public class MyTools {
@Tool(description = "Analyze a chess position using Stockfish.")
ToolResponse stockfish(@ToolArg(description = "FEN of the chess position") String fen) {
int depth = 15;
int timeoutSeconds = 3;
String command = """
expect -c "spawn stockfish; \
send \"uci\r\"; \
send \"setoption name MultiPV value 2\r\"; \
send \"position fen %s\r\"; \
send \"go depth %d\r\"; \
sleep %d; \
send \"quit\r\"; interact"
""".formatted(fen, depth, timeoutSeconds);
return ToolResponse.success(new TextContent($(command).get()));
}
}
Note the very convenient $(command).get()
, which uses Jash - a Java library to provide a fluent interface to Process
.
It really is a nice API to run shell commands from Java.
The expect
utility handles interaction with the Stockfish binary because unlike typical CLI applications where an invocation gets all the parameters and represents a complete unit of computation, Stockfish CLI starts and then you send commands to it both for configuration and chess analysis. It's more convenient when you need to analyze sequences of moves at once, but a bit awkward as a CLI to integrate against.
Anyway, we package our MCP server as a Docker container using this Dockerfile: https://github.com/shelajev/mcp-stockfish/blob/main/src/main/docker/Dockerfile.jvm
This Dockerfile uses multi-stage build to compile the Stockfish binary and then the standard Quarkus boilerplate instructions the app.
And of course we copy the Stockfish binary to the final image too:
COPY --from=stockfish_builder /opt/Stockfish/src/stockfish /usr/local/bin/stockfish
Building and Running the Server
Build the Quarkus application using:
./mvnw verify -Dquarkus.container-image.build=true
The Docker image will be tagged as shelajev/mcp-stockfish:0.0.1
. Run the server using:
docker run -p 8080:8080 shelajev/mcp-stockfish:0.0.1
Testing our glorious MCP
Verify the server works using the MCP inspector by running:
npx @modelcontextprotocol/inspector
Then connect it to http://localhost:8080/mcp
where Quarkus MCP Server extension hosts the endpoint (you can override the config, but for use the defaults suffice):
Click on the tools, and the list tools button. Then manually call the MCP server to verify its functionality.
Consider this famous endgame study by Richard Réti. It's FEN, the notation describing a chess postion, which we'll be passing to the MCP server and Stockfish is 7K/8/k1P5/7p/8/8/8/8 w - - 0 1
.
You can see in the output that Stockfish analyzes the position and correctly suggests Kg7
as the optimal move, leading to a surprising draw.
Integration with AI assitants
You can of course integrate this MCP server into any AI assistant that supports the protocol. As an exercise for the reader, try to configure Goose, which we set up in a previous article to use our Stockfish MCP.
We'll integrate it into VS Code:
In the workspace create the mcp.json
file and configure the server like this:
{
"servers": {
"stockfish": {
"name": "Stockfish",
"url": "http://localhost:8080/mcp",
"type": "http"
}
}
}
And click the start button on the server definition so VS Code will connect to it:
Now all that is left is to use the chat in the Agent mode, so it has access to tools, and request to analyze chess positions:
Conclusion
Creating an MCP server in Java is super straightforward,
and is a great way to enhance AI assistants with predictable, repeatable functionality.
Running MCP servers in Docker adds isolation, reproducibility, and security benefits, so in general one should probably prefer that over running naked npx servers and other similar approaches.
But also you don't have to roll MCP servers yourself for most standard APIs you want to integrate with.
For typical integrations (Slack, Notion, GitHub), there's Docker’s MCP toolkit which makes working with MCP even better providing discovery, simplified installation, secrets management, access control, etc -- all the good things you want if you're building production grade systems.
Top comments (0)