lichess-mcp
MCP server that exposes the Lichess public API through tools for querying player profiles, games, analysis, openings, puzzles, and tournaments, allowing natural-language chess questions without an API key.
README
lichess-mcp
An MCP server that puts the Lichess public API in front of any MCP-compatible agent, so you can ask about chess in plain language instead of reading JSON.
"How did Magnus do in blitz this week, and what did the engine think of his last loss?"
No API key, no account, no OAuth — every tool here uses Lichess' public endpoints.
<!-- Demo GIF: record a short Claude Desktop session and save it to docs/demo.gif, then
uncomment the line below. -->
<!--
-->
What you get
| Tool | What it answers |
|---|---|
get_user_profile |
Ratings in every format, title, country, account stats, current win/loss streak |
get_recent_games |
Recent games with PGN, result, opponent, opening and accuracy; filter by format or colour |
get_game_analysis |
Per-side accuracy and ACPL, plus every blunder/mistake/inaccuracy with the engine's preferred move and the eval swing |
get_opening_stats |
Win/draw/loss and score% for one opening, for one player, as a given colour |
analyze_position |
Top engine lines for a FEN, from Lichess' cloud evaluation cache, rendered in SAN |
get_puzzle_of_day |
Today's daily puzzle: FEN, themes, rating, and the solution |
search_players |
Autocomplete a half-remembered username |
get_tournament_info |
Arena or Swiss tournament: time control, player count, games played, standings |
Plus a resource, lichess://api-reference, summarising the endpoints behind each tool, the
rate limits, and the known gaps — so an agent can read the manual instead of guessing.
Output is shaped for reading, not parsing
Raw Lichess payloads bury the result of a game under ninety clock timestamps. Every tool here returns a small dict with obvious keys:
// get_recent_games("DrNykterstein", count=1, format="blitz")
{
"game_id": "kAdOQKeh",
"url": "https://lichess.org/kAdOQKeh",
"played_at": "2026-04-08T19:39:03+00:00",
"format": "blitz",
"time_control": "3+0",
"opening": "Alekhine Defense: Sämisch Attack",
"color": "black",
"result": "win",
"my_rating": 3145,
"rating_change": 8,
"my_accuracy": 93,
"opponent": { "username": "respects_55", "rating": 2644, "accuracy": 89 },
"pgn": "[Event \"Take Take Take Arena\"]\n..."
}
Engine lines come back as SAN, because 1... e5 2. g3 Nf6 is legible and e7e5 g2g3 g8f6
is not. Evaluations are normalised so a positive score always favours the side to move, and
forced mates are reported as mate_in rather than a huge centipawn number.
Install
Requires Python 3.10+.
uvx lichess-mcp
or
pip install lichess-mcp
Claude Desktop
Add this to your claude_desktop_config.json
(macOS: ~/Library/Application Support/Claude/claude_desktop_config.json,
Windows: %APPDATA%\Claude\claude_desktop_config.json), then restart Claude Desktop:
{
"mcpServers": {
"lichess": {
"command": "uvx",
"args": ["lichess-mcp"]
}
}
}
If you installed with pip rather than using uvx, point at the installed script instead:
{
"mcpServers": {
"lichess": {
"command": "lichess-mcp"
}
}
}
Claude Code
claude mcp add lichess -- uvx lichess-mcp
Try these
-
"What's DrNykterstein's blitz rating, and is he on a streak right now?" →
get_user_profile -
"Show me my last 5 rapid games as Black and tell me which openings went badly." →
get_recent_games, thenget_opening_stats -
"Pull up today's Lichess puzzle and give me the position — don't tell me the answer yet." →
get_puzzle_of_day -
"Here's a FEN from my game —
r1bqkbnr/pppp1ppp/2n5/4p3/2B1P3/5N2/PPPP1PPP/RNBQK2R b KQkq - 3 3. What does the engine want to play?" →analyze_position -
"Find every blunder in lichess.org/dmvL2duu and explain what each one missed." →
get_game_analysis
Openings, tournaments and player search work the same way: "How do I score with the Sicilian as White over my last 200 games?", "Who won tournament W1OrjDLM?", "There's a player called something like 'penguin' — find them."
Configuration
Everything is optional.
| Variable | Default | Purpose |
|---|---|---|
LICHESS_API_TOKEN |
unset | A personal access token. Raises your rate limit and unlocks your own private data. Nothing here requires it. |
LICHESS_MCP_MIN_INTERVAL |
1.0 |
Seconds between requests. Lichess asks for 1 req/sec; lower it only with a token and a good reason. |
LICHESS_MCP_MAX_RETRY_AFTER |
60 |
Longest 429 back-off to sit out before reporting the rate limit to the caller. |
LICHESS_MCP_TIMEOUT |
30 |
Per-request timeout in seconds. |
LICHESS_MCP_HTTP_LOG_LEVEL |
WARNING |
Set to INFO to log every outgoing request. |
Being a good API citizen
Lichess is free, donation-funded, and asks clients for at most one request per second.
This server enforces that globally with an async rate limiter rather than trusting each tool
to behave, and backs off politely on HTTP 429. That means tools which scan many games
(get_opening_stats with a large max_games) are deliberately unhurried.
If you want the whole games database, take it from database.lichess.org, not from this server.
Known limits
- Computer analysis is opt-in on Lichess.
get_game_analysisand theaccuracyfields only have data for games where a player requested analysis. Games without it returnanalysis_available: falseand say so, rather than failing. analyze_positionreads a cache, not a live engine. Lichess' cloud eval covers positions someone has already analysed — common openings and popular games. Novel positions returncached: falsewith an explanation.get_opening_statssamples recent games. Lichess' personal opening explorer now requires OAuth, so this aggregates the games export instead. Results describe the lastmax_gamesgames (default 200, max 500), not a lifetime total.- Streaks are derived, not fetched — Lichess has no streak endpoint, so
get_user_profilecomputes the current run from the 30 most recent rated games.
Development
git clone https://github.com/Anay704/lichess-mcp
cd lichess-mcp
python -m venv .venv && .venv/bin/pip install -e ".[dev]"
.venv/bin/pytest # offline, sub-second
.venv/bin/ruff check .
The suite stubs the HTTP layer, so the default run is fast and works offline. A handful of tests that really call lichess.org are opt-in:
LICHESS_MCP_LIVE_TESTS=1 .venv/bin/pytest
License
MIT — see LICENSE.
Not affiliated with or endorsed by Lichess. Lichess is a free/libre, open-source chess server; if you get value out of this, consider donating to them.
Recommended Servers
playwright-mcp
A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.
Magic Component Platform (MCP)
An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.
Audiense Insights MCP Server
Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.
VeyraX MCP
Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.
graphlit-mcp-server
The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.
Kagi MCP Server
An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.
Neon Database
MCP server for interacting with Neon Management API and databases
E2B
Using MCP to run code via e2b.
Exa Search
A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.
Qdrant Server
This repository is an example of how to create a MCP server for Qdrant, a vector search engine.