A Stockfish-powered chess engine exposed as an MCP server. Calculates best moves and supports both HTTP/SSE and stdio transports.
A Stockfish-powered chess engine exposed as an MCP server using FastMCP. Calculates best moves via MCP tools accessible over SSE (default) or stdio transports using an MCP client library. Part of the ChessPal project.
Install the published package from PyPI using pip:
pip install chesspal-mcp-engine
Installation for development
git clone https://github.com/wilson-urdaneta/dylangames-mcp-chess-engine.git
cd dylangames-mcp-chess-engine
poetry install
CHESSPAL_ENGINE_PATH
environment variable to point to your Stockfish binary# All variables have defaults, override as needed
export CHESSPAL_ENGINE_NAME=stockfish # Default: stockfish
export CHESSPAL_ENGINE_VERSION=17.1 # Default: 17.1
export CHESSPAL_ENGINE_OS=macos # Default: automatically detected based on platform
export CHESSPAL_ENGINE_BINARY=stockfish # Default: stockfish (include .exe for Windows)
The ChessPal Chess Engine requires a Stockfish binary to run the server and integration tests. You have three options for setting up the binary:
Point to any Stockfish executable on your system:
# Unix-like systems (binary from apt/brew or downloaded)
export CHESSPAL_ENGINE_PATH=/usr/local/bin/stockfish
# Windows (PowerShell)
$env:CHESSPAL_ENGINE_PATH="C:\path\to\stockfish.exe"
The binary can be:
apt install stockfish
, brew install stockfish
)If CHESSPAL_ENGINE_PATH
is not set, the server will look for the binary in a predefined directory structure:
engines/stockfish/<version>/<os>/<binary_name>
engines/README.md
for the exact directory structureCHESSPAL_ENGINE_OS
environment variable to match your system:
export CHESSPAL_ENGINE_OS=macos # For macOS
export CHESSPAL_ENGINE_OS=linux # For Linux
export CHESSPAL_ENGINE_OS=windows # For Windows
Advanced users can compile Stockfish from source using our separate dylangames-engine
repository. This option provides maximum control over the build configuration but requires C++ development experience.
The server uses FastMCP with support for both Server-Sent Events (SSE) and stdio transports. You can start it using:
poetry run python -m chesspal_mcp_engine.main
# Or
poetry run python -m chesspal_mcp_engine.main --transport sse
This command starts the MCP server in SSE mode, which listens for SSE connections on the configured host and port (default: 127.0.0.1:9000). This mode is ideal for programmatic clients and agents that need to interact with the chess engine over HTTP.
You can also use the entry point command:
poetry run chesspal-mcp-engine
poetry run python -m chesspal_mcp_engine.main --transport stdio
# Or
poetry run chesspal-mcp-engine --transport stdio
This command starts the MCP server in stdio mode, which communicates through standard input/output. This mode is useful for direct integration with tools like Claude Desktop or for testing purposes.
The module exposes the following endpoints through FastMCP:
get_best_move_tool
: Get the best move for a given chess positionvalidate_move_tool
: Validate if a move is legal in a given positionget_legal_moves_tool
: Get all legal moves in a given positionget_game_status_tool
: Get the current game status (in progress, checkmate, etc.)Example request using the MCP SSE client:
from mcp.client.sse import sse_client
from mcp import ClientSession
async def get_best_move():
# Connect to the SSE endpoint
async with sse_client("http://127.0.0.1:9000/sse", timeout=10.0) as streams:
# Create an MCP session
async with ClientSession(*streams) as session:
# Initialize the session
await session.initialize()
# Call the tool - Note: Arguments MUST be wrapped in a "request" field
result = await session.call_tool('get_best_move_tool', {
"request": { # Required wrapper field
"fen": "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1",
"move_history": []
}
})
print(f"Best move: {result.best_move_uci}") # e.g., "e2e4"
The get_best_move_tool
expects requests in the following format:
{
"request": {
"fen": "string", // Required: FEN string representing the position
"move_history": [] // Optional: List of previous moves in UCI format
}
}
Note: The outer "request" wrapper field is required for proper request validation.
The engine is configured with the following timeouts:
CHESSPAL_ENGINE_TIMEOUT_MS
)These timeouts ensure reliable operation while allowing sufficient time for move calculation, even on slower systems or when the engine needs more time to process complex positions.
The module uses the following environment variables for configuration:
# Primary configuration
CHESSPAL_ENGINE_PATH=/path/to/your/engine/binary
# Fallback configuration (used if CHESSPAL_ENGINE_PATH is not set/invalid)
CHESSPAL_ENGINE_NAME=stockfish # Default: stockfish
CHESSPAL_ENGINE_VERSION=17.1 # Default: 17.1
CHESSPAL_ENGINE_OS=macos # Default: auto-detected based on platform
CHESSPAL_ENGINE_BINARY=stockfish # Default: stockfish (include .exe for Windows)
# Engine parameters
CHESSPAL_ENGINE_DEPTH=10 # Default: 10
CHESSPAL_ENGINE_TIMEOUT_MS=1000 # Default: 1000
# MCP Server Configuration
MCP_HOST=127.0.0.1 # Default: 127.0.0.1
MCP_PORT=9000 # Default: 9000
# Logging configuration
ENVIRONMENT=development # Default: development
LOG_LEVEL=INFO # Default: INFO for production, DEBUG for development
See .env.example
for a complete example configuration.
dylangames-mcp-chess-engine/
├── src/ # Source code
│ └── chesspal_mcp_engine/
│ ├── __init__.py
│ ├── main.py # FastMCP server
│ ├── engine_wrapper.py # Stockfish wrapper
│ ├── config.py # Configuration management
│ ├── logging_config.py # Logging setup
│ ├── shutdown.py # Graceful shutdown handling
│ └── models.py # Data models
├── tests/ # Test suite
│ └── test_engine_wrapper.py
├── engines/ # Engine binaries directory
├── pyproject.toml # Poetry dependencies and configuration
├── poetry.lock # Locked dependencies
├── .env.example # Environment variables example
└── README.md # This file
poetry install
poetry shell
poetry run pytest
poetry run pytest tests/ -v
poetry run black .
poetry run isort .
poetry run flake8
poetry run pre-commit run --all-files
poetry run mcp dev src/chesspal_mcp_engine/main.py
# In the inspector UI
# STDIO configuration
Command: poetry
Arguments: run python -m chesspal_mcp_engine.main --transport stdio
# SSE
# In a separate terminal run the app in SSE mode
poetry run python -m chesspal_mcp_engine.main
# In the mcp inspector UI
Transport Type > SSE
{
"fen": "r3k2r/p1ppqpb1/bn2pnp1/3PN3/1p2P3/2N2Q1p/PPPBBPPP/R3K2R w KQkq - 0 1",
"move_history": []
}
To add new dependencies:
# Add a production dependency
poetry add package-name
# Add a development dependency
poetry add --group dev package-name
The codebase follows these standards:
poetry run black .
poetry run isort .
poetry run flake8
poetry run pytest
The project uses GitHub Actions for continuous integration and deployment. The pipeline is triggered on:
main
branchmain
branchv
(e.g., v1.0.0)Lint (lint
job)
Test (test
job)
Package (package
job)
Release (release
job)
The project uses semantic versioning with two types of tags:
External Releases (e.g., v1.0.0
)
Internal Releases (e.g., v1.0.0-internal
)
PyPI publishing is disabled by default. To enable:
ENABLE_PYPI
to true
in the workflow filePYPI_TOKEN
secret in GitHub repository settingsGNU General Public License v3.0 - see LICENSE file for details.
For issues and feature requests, please use the GitHub issue tracker.
The project includes both unit tests and integration tests:
poetry run pytest
This runs the complete test suite. Note that integration tests require a Stockfish binary to be available through either Option 1 or 2 above.
poetry run pytest -m "not integration"
This runs only the unit tests, where Stockfish interaction is mocked and no binary is required.