Chess MCP
Chess MCP App
A ChatGPT Chess application built with OpenAI Apps SDK, allowing you to play chess through conversation with an interactive board widget.
Now following OpenAI Apps SDK best practices!
Features
š® Play chess using algebraic notation (e4, Nf3, O-O, etc.)
š Interactive chess board widget in ChatGPT
š¤ AI opponent suggestions (ChatGPT can play moves)
š Stockfish engine analysis integration
š Move history tracking
ā Full move validation and game state management
š Game status and player information display
š§© Mate in 1 tactical puzzles (Easy, Medium, Hard)
Architecture
Backend: Python MCP Server using FastMCP with python-chess
Frontend: React component with chess.js + react-chessboard
Build System: Vite for optimal development experience
Integration: OpenAI Apps SDK patterns with proper hooks
Project Structure
ChessMCP/
āāā server/
ā āāā main.py # Python MCP server (renamed from server.py)
ā āāā requirements.txt # Python dependencies
āāā src/
ā āāā chess-board/ # Chess board component
ā ā āāā index.tsx
ā āāā types.ts # Shared TypeScript types
ā āāā use-openai-global.ts # Hook for window.openai access
ā āāā use-widget-state.ts # Hook for widget state
ā āāā use-widget-props.ts # Hook for tool props
āāā assets/ # Build output (generated by Vite)
ā āāā chess-board.html
āāā vite.config.mts # Vite configuration
āāā package.json # Root dependencies
āāā tsconfig.json # TypeScript config
āāā README.mdInstallation
Prerequisites
Python 3.8+
Node.js 18+
Stockfish chess engine (optional, for analysis)
Setup Steps
Install Python dependencies:
cd server
pip3 install -r requirements.txtInstall Stockfish (optional, for engine analysis):
# macOS
brew install stockfish
# Ubuntu/Debian
sudo apt-get install stockfishInstall Node.js dependencies:
npm installBuild the frontend component:
npm run buildThis generates assets/chess-board.html which the server loads.
The MCP server is configured in your
~/.cursor/mcp.json:
{
"mcpServers": {
"chess": {
"command": "python3",
"args": ["/path/to/ChessMCP/server/main.py"],
"env": {
"PYTHONPATH": "/path/to/ChessMCP/server"
}
}
}
}Development Workflow
Build Once (Production)
npm run buildDevelopment Mode (with hot reload)
# Terminal 1: Start Vite dev server
npm run dev
# Terminal 2: Start Python server
cd server
python3 main.pyServe Built Assets (for testing)
npm run serveTesting Locally (No ChatGPT Required!)
Option 1: Direct Local Tester (Recommended)
Play chess directly without server/OAuth:
python3 chess_local_test.pyCommands:
āļø > move e4
āļø > move e5
āļø > status
āļø > stockfish
āļø > puzzle mediumš See: LOCAL_TESTING.md
Option 2: HTTP Client
Test via HTTP (requires server running):
# Terminal 1: Start server
cd server && python3 main.py
# Terminal 2: Start client
python3 chess_client.pyš See: CLIENT_USAGE.md
Testing with ChatGPT
The Chess MCP server now includes Google OAuth 2.1 authentication for secure ChatGPT integration!
š Quick Start: OAUTH_QUICK_START.md (5 minutes)
š Detailed Setup: GOOGLE_OAUTH_SETUP.md (Step-by-step)
š Next Steps: NEXT_STEPS.md (What to do now)
š Troubleshooting: CHATGPT_CONNECTOR_TROUBLESHOOTING.md
Quick start:
# 1. Set up Google OAuth credentials (see GOOGLE_OAUTH_SETUP.md)
# 2. Create server/.env with credentials
# Terminal 1: Start server
cd server
pip3 install -r requirements.txt
python3 main.py
# Terminal 2: Expose with ngrok
ngrok http 8000
# Update server/.env with ngrok URL, restart server
# Then add connector in ChatGPT Settings > Connectors
# URL format: https://YOUR-SUBDOMAIN.ngrok-free.app (no /mcp suffix)Usage
Starting a Game
In ChatGPT, start a chess game by making your first move:
ChessMCP e4or
Let's play chess! I'll start with e4The interactive chess board will appear showing your move.
Making Moves
Simply type your move in algebraic notation:
Nf3
e5
Bc4
Nc6Supported notation:
Basic moves:
e4,Nf3,d5Captures:
exd5,Nxf7Castling:
O-O(kingside),O-O-O(queenside)Pawn promotion:
e8=Q,a1=NCheck:
Qh5+Checkmate:
Qf7#
Additional Commands
Check game status:
chess_status
What's the current status?Load a puzzle:
Show me a chess puzzle
Give me a hard puzzleGet engine analysis:
Ask Stockfish for the best moveReset game:
chess_reset
Let's start a new gameMCP Tools
The server exposes five tools:
chess_move
Input:
move(string) - Algebraic notationOutput: Updated board state with FEN, move history, game status
Widget: Renders interactive chess board
chess_stockfish
Input:
depth(int, default: 15) - Analysis depthOutput: Best move, evaluation, principal variation
Widget Accessible: Can be called from the widget UI
chess_reset
Input: None
Output: Confirmation of reset
Widget: Shows fresh starting position
chess_status ā
Input: None
Output: Game status, current turn, player names, move count, recent moves
Use: Check game progress and who's moving
chess_puzzle ā
Input:
difficulty(string: "easy", "medium", "hard")Output: Mate-in-1 puzzle position with hint
Widget: Shows puzzle position on the board
Use: Practice tactical patterns and checkmate recognition
React Hooks (Apps SDK Patterns)
The component uses OpenAI Apps SDK hooks for clean, reactive code:
useOpenAiGlobal(key)
Access window.openai properties reactively:
const theme = useOpenAiGlobal("theme");
const displayMode = useOpenAiGlobal("displayMode");useToolOutput<T>()
Get the current tool output:
const toolOutput = useToolOutput<ChessToolOutput>();
// Returns: { fen, move, status, turn }useToolResponseMetadata<T>()
Get tool response metadata:
const metadata = useToolResponseMetadata<ChessMetadata>();
// Returns: { move_history_list, legal_moves, etc. }useWidgetState<T>(defaultState)
Persist component state across sessions:
const [widgetState, setWidgetState] = useWidgetState<ChessWidgetState>({
lastDepth: 15,
analysisVisible: false
});Build System (Vite)
Why Vite?
ā”ļø Fast hot module replacement during development
š¦ Optimized production builds
šÆ TypeScript support out of the box
š§ Better error messages
šØ Source maps for debugging
Build Output
The build creates a single HTML file containing:
Bundled React component
All JavaScript dependencies
Inline CSS
Proper structure for Skybridge runtime
Configuration
See vite.config.mts for the build configuration. The setup:
Bundles
src/chess-board/index.tsxIncludes all dependencies
Wraps in HTML with proper structure
Outputs to
assets/chess-board.html
Server Architecture
Resource Handling
The server follows Apps SDK patterns:
# Load HTML from assets
@lru_cache(maxsize=None)
def load_widget_html(component_name: str) -> str:
html_path = ASSETS_DIR / f"{component_name}.html"
return html_path.read_text(encoding="utf8")
# Proper MIME type
MIME_TYPE = "text/html+skybridge"
# Resource registration
@mcp._mcp_server.list_resources()
async def list_resources() -> List[types.Resource]:
return [types.Resource(...)]
# Resource handler
async def handle_read_resource(req) -> types.ServerResult:
html = load_widget_html("chess-board")
return types.ServerResult(types.ReadResourceResult(...))Tool Metadata
All tools include proper metadata:
{
"openai/outputTemplate": "ui://widget/chess-board.html",
"openai/widgetAccessible": True,
"openai/resultCanProduceWidget": True,
"openai/toolInvocation/invoking": "Making move...",
"openai/toolInvocation/invoked": "Move played"
}Troubleshooting
Widget Not Rendering
Ensure component is built:
npm run buildVerify
assets/chess-board.htmlexistsCheck server logs for errors
Stockfish Not Found
Update the path in server/main.py:
STOCKFISH_PATH = "/path/to/stockfish"Build Errors
If TypeScript errors occur:
npm run typecheckServer Won't Start
Make sure all Python dependencies are installed:
cd server
pip3 install -r requirements.txtWhat's New in This Version
⨠Restructured Project
Moved from
web/tosrc/directoryRoot-level
package.jsonandvite.config.mtsProper Apps SDK project structure
š£ React Hooks
useOpenAiGlobalfor reactive window.openai accessuseWidgetStatefor persistent state managementuseToolOutputanduseToolResponseMetadatafor props
ā” Vite Build System
Replaced esbuild with Vite
Hot module replacement in development
Better TypeScript support
Faster builds
šļø Server Improvements
Proper resource loading from
assets/Correct MIME type (
text/html+skybridge)Better error handling
CORS middleware for development
š Better Types
Comprehensive TypeScript types
Apps SDK-compatible interfaces
Chess-specific type definitions
Contributing
Feel free to enhance the app with:
Opening analysis and endgame tablebases
Multiple game sessions
PGN import/export
Time controls
Online multiplayer
More puzzle types
License
MIT License - feel free to use and modify!