Skip to main content
Glama

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.md

Installation

Prerequisites

  • Python 3.8+

  • Node.js 18+

  • Stockfish chess engine (optional, for analysis)

Setup Steps

  1. Install Python dependencies:

cd server pip3 install -r requirements.txt
  1. Install Stockfish (optional, for engine analysis):

# macOS brew install stockfish # Ubuntu/Debian sudo apt-get install stockfish
  1. Install Node.js dependencies:

npm install
  1. Build the frontend component:

npm run build

This generates assets/chess-board.html which the server loads.

  1. 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 build

Development Mode (with hot reload)

# Terminal 1: Start Vite dev server npm run dev # Terminal 2: Start Python server cd server python3 main.py

Serve Built Assets (for testing)

npm run serve

Testing Locally (No ChatGPT Required!)

Option 1: Direct Local Tester (Recommended)

Play chess directly without server/OAuth:

python3 chess_local_test.py

Commands:

ā™Ÿļø > 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 e4

or

Let's play chess! I'll start with e4

The interactive chess board will appear showing your move.

Making Moves

Simply type your move in algebraic notation:

Nf3 e5 Bc4 Nc6

Supported notation:

  • Basic moves: e4, Nf3, d5

  • Captures: exd5, Nxf7

  • Castling: O-O (kingside), O-O-O (queenside)

  • Pawn promotion: e8=Q, a1=N

  • Check: 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 puzzle

Get engine analysis:

Ask Stockfish for the best move

Reset game:

chess_reset Let's start a new game

MCP Tools

The server exposes five tools:

chess_move

  • Input: move (string) - Algebraic notation

  • Output: Updated board state with FEN, move history, game status

  • Widget: Renders interactive chess board

chess_stockfish

  • Input: depth (int, default: 15) - Analysis depth

  • Output: 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:

  1. Bundles src/chess-board/index.tsx

  2. Includes all dependencies

  3. Wraps in HTML with proper structure

  4. 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

  1. Ensure component is built: npm run build

  2. Verify assets/chess-board.html exists

  3. Check 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 typecheck

Server Won't Start

Make sure all Python dependencies are installed:

cd server pip3 install -r requirements.txt

What's New in This Version

✨ Restructured Project

  • Moved from web/ to src/ directory

  • Root-level package.json and vite.config.mts

  • Proper Apps SDK project structure

šŸŽ£ React Hooks

  • useOpenAiGlobal for reactive window.openai access

  • useWidgetState for persistent state management

  • useToolOutput and useToolResponseMetadata for 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!

Resources

-
security - not tested
F
license - not found
-
quality - not tested

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/GeneralJerel/ChessMCP'

If you have feedback or need assistance with the MCP directory API, please join our Discord server