Skip to main content
Glama
README.md
# 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**:
```bash
cd server
pip3 install -r requirements.txt
```

2. **Install Stockfish** (optional, for engine analysis):
```bash
# macOS
brew install stockfish

# Ubuntu/Debian
sudo apt-get install stockfish
```

3. **Install Node.js dependencies**:
```bash
npm install
```

4. **Build the frontend component**:
```bash
npm run build
```

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

5. **The MCP server is configured** in your `~/.cursor/mcp.json`:
```json
{
  "mcpServers": {
    "chess": {
      "command": "python3",
      "args": ["/path/to/ChessMCP/server/main.py"],
      "env": {
        "PYTHONPATH": "/path/to/ChessMCP/server"
      }
    }
  }
}
```

## Development Workflow

### Build Once (Production)
```bash
npm run build
```

### Development Mode (with hot reload)
```bash
# Terminal 1: Start Vite dev server
npm run dev

# Terminal 2: Start Python server
cd server
python3 main.py
```

### Serve Built Assets (for testing)
```bash
npm run serve
```

## Testing Locally (No ChatGPT Required!)

### Option 1: Direct Local Tester (Recommended)

Play chess directly without server/OAuth:

```bash
python3 chess_local_test.py
```

Commands:
```
ā™Ÿļø  > move e4
ā™Ÿļø  > move e5
ā™Ÿļø  > status
ā™Ÿļø  > stockfish
ā™Ÿļø  > puzzle medium
```

šŸ“– **See:** [LOCAL_TESTING.md](./LOCAL_TESTING.md)

### Option 2: HTTP Client

Test via HTTP (requires server running):

```bash
# Terminal 1: Start server
cd server && python3 main.py

# Terminal 2: Start client
python3 chess_client.py
```

šŸ“– **See:** [CLIENT_USAGE.md](./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](./OAUTH_QUICK_START.md) (5 minutes)  
šŸ“– **Detailed Setup:** [GOOGLE_OAUTH_SETUP.md](./GOOGLE_OAUTH_SETUP.md) (Step-by-step)  
šŸ“– **Next Steps:** [NEXT_STEPS.md](./NEXT_STEPS.md) (What to do now)  
šŸ“– **Troubleshooting:** [CHATGPT_CONNECTOR_TROUBLESHOOTING.md](./CHATGPT_CONNECTOR_TROUBLESHOOTING.md)

Quick start:
```bash
# 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:
```tsx
const theme = useOpenAiGlobal("theme");
const displayMode = useOpenAiGlobal("displayMode");
```

### `useToolOutput<T>()`
Get the current tool output:
```tsx
const toolOutput = useToolOutput<ChessToolOutput>();
// Returns: { fen, move, status, turn }
```

### `useToolResponseMetadata<T>()`
Get tool response metadata:
```tsx
const metadata = useToolResponseMetadata<ChessMetadata>();
// Returns: { move_history_list, legal_moves, etc. }
```

### `useWidgetState<T>(defaultState)`
Persist component state across sessions:
```tsx
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:

```python
# 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:
```python
{
    "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`:
```python
STOCKFISH_PATH = "/path/to/stockfish"
```

### Build Errors

If TypeScript errors occur:
```bash
npm run typecheck
```

### Server Won't Start

Make sure all Python dependencies are installed:
```bash
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

- [OpenAI Apps SDK Documentation](https://developers.openai.com/apps-sdk)
- [Apps SDK Examples](https://github.com/openai/openai-apps-sdk-examples)
- [python-chess Documentation](https://python-chess.readthedocs.io/)
- [chess.js](https://github.com/jhlywa/chess.js)
- [react-chessboard](https://github.com/Clariity/react-chessboard)