GB-Power-Market-JJ play-chess

Play live chess against your user on ChessWithClaw. Use when: (1) User sends a chess invite URL containing chesswithclaw.vercel.app, (2) User asks you to play chess, (3) User mentions ChessWithClaw, (4) User says "I challenged you to chess", (5) User sends a game ID or token for a chess game, (6) User mentions "npx clawhub install play-chess". When triggered, connect to the game immediately and wait for the human to move first — you are always Black.

install
source · Clone the upstream repo
git clone https://github.com/GeorgeDoors888/GB-Power-Market-JJ
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/GeorgeDoors888/GB-Power-Market-JJ "$T" && mkdir -p ~/.claude/skills && cp -r "$T/openclaw-skills/skills/alightttt/play-chess" ~/.claude/skills/georgedoors888-gb-power-market-jj-play-chess && rm -rf "$T"
OpenClaw · Install into ~/.openclaw/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/GeorgeDoors888/GB-Power-Market-JJ "$T" && mkdir -p ~/.openclaw/skills && cp -r "$T/openclaw-skills/skills/alightttt/play-chess" ~/.openclaw/skills/georgedoors888-gb-power-market-jj-play-chess && rm -rf "$T"
manifest: openclaw-skills/skills/alightttt/play-chess/SKILL.md
source content

ChessWithClaw — Complete Playing Guide

What Is ChessWithClaw

ChessWithClaw is a real-time chess platform where YOU (the OpenClaw agent) play chess against your human user. You are always Black. The human is always White and moves first. The game is live — every move appears on both sides instantly.

Base URL:

https://chesswithclaw.vercel.app
API base:
https://chesswithclaw.vercel.app/api


Step 1 — Extract Game Credentials

When the user sends an invite, extract these from the URL:

https://chesswithclaw.vercel.app/Agent?id=GAME_ID&token=AGENT_TOKEN
  • GAME_ID
    — UUID identifying the game (e.g.
    0ea3c8b2-4fe9-4873-bef5-10a51f576464
    )
  • AGENT_TOKEN
    — Your authentication token (e.g.
    7764c2b6-e646-4945-91b7-dfc95858d489
    )

Store both. You need them for every API call.

CRITICAL — TOKEN GOES IN HEADER ONLY Every single API request MUST include this header:

x-agent-token: AGENT_TOKEN
Do NOT put the token in the request body. Header only. Requests without this header return 401 Unauthorized.


Step 2 — Connect to the Game

Best method for OpenClaw: Long-Polling (Option D)

It's the simplest, most reliable method. No persistent connection needed.

Connection Loop

GET https://chesswithclaw.vercel.app/api/poll
  ?id=GAME_ID
  &last_move_count=0
  &last_chat_count=0

Headers:
  x-agent-token: AGENT_TOKEN

Poll every 2 seconds. The server returns immediately with one of:

eventMeaningYour action
waiting
Human hasn't moved yetWait 2s, poll again
your_turn
Human moved, your turnMake your move
human_chatted
User sent a messageRead it, optionally reply
game_ended
Game is overAcknowledge, notify user

Update

last_move_count
and
last_chat_count
with values from each response. The
waiting
response includes
retry_after: 2
— wait exactly that many seconds before polling again.

Confirming Connection

The first time you hit

/api/poll
, the server marks you as connected. Tell the user: "I'm connected and waiting for your first move!"


Step 3 — Reading the Game State

When

event: "your_turn"
, the response includes everything you need:

{
  "event": "your_turn",
  "fen": "rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq e3 0 1",
  "turn": "b",
  "move_number": 1,
  "last_move": { "from": "e2", "to": "e4", "san": "e4", "uci": "e2e4" },
  "legal_moves": ["e7e5", "c7c5", "e7e6", "g8f6", ...],
  "legal_moves_uci": ["e7e5", "c7c5", "e7e6", ...],
  "board_ascii": "  +------------------------+\n8 | r  n  b  q  k  b  n  r |\n...",
  "in_check": false,
  "is_checkmate": false,
  "is_stalemate": false,
  "material_balance": { "white": 39, "black": 39, "advantage": "equal" },
  "move_history": ["e2e4"],
  "move_count": 1,
  "chat_count": 0
}

Critical rule: ONLY play moves from

legal_moves_uci
. Never invent moves.


Step 4 — Reading the Board (FEN)

FEN string format:

pieces turn castling en-passant halfmove fullmove

Example:

rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq e3 0 1

  • Uppercase = White pieces, lowercase = Black (your) pieces
  • K/k
    =King
    Q/q
    =Queen
    R/r
    =Rook
    B/b
    =Bishop
    N/n
    =Knight
    P/p
    =Pawn
  • Numbers = consecutive empty squares
  • b
    after pieces = Black to move (your turn)
  • Use
    board_ascii
    for a visual layout — easier to read

Step 5 — Submitting Your Move

POST https://chesswithclaw.vercel.app/api/move

Headers:
  Content-Type: application/json
  x-agent-token: AGENT_TOKEN

Body:
{
  "id": "GAME_ID",
  "move": "e7e5",
  "reasoning": "Controlling the center with symmetry response"
}

Move Format (UCI)

  • Normal move:
    e7e5
    (from-square + to-square)
  • Capture:
    d5e4
    (same format — server knows it's a capture)
  • Castling kingside:
    e8g8
    (Black)
  • Castling queenside:
    e8c8
    (Black)
  • En passant:
    e5d6
    (move to the square the pawn passed through)
  • Pawn promotion:
    e7e8q
    (add piece letter: q=queen, r=rook, b=bishop, n=knight)
  • Always promote to queen unless you have a specific reason not to

After Submitting

  • Success:
    { "success": true, "game": { ... } }
  • Resume polling immediately with updated
    last_move_count

Chess Strategy — How to Play Well

Opening principles (moves 1-10):

  • Control the center: play e5, d5, c5, or Nf6 as Black responses
  • Develop knights before bishops
  • Castle early (kingside preferred: e8g8)
  • Don't move the same piece twice unless necessary
  • Don't bring queen out too early

Middlegame principles:

  • Look for tactics: forks, pins, skewers, discovered attacks
  • Keep your king safe — avoid opening files toward your king
  • Centralize your pieces
  • Rooks belong on open files
  • Material values: Pawn=1, Knight=3, Bishop=3, Rook=5, Queen=9

Endgame principles:

  • King becomes active — centralize it
  • Passed pawns (no opposing pawns blocking) are powerful — push them
  • Rook + King can force checkmate vs lone king
  • If behind on material, look for perpetual check or stalemate tricks

Evaluating the position: Use

material_balance
from the payload:

  • advantage: "equal"
    — play solid, strategic chess
  • advantage: "white"
    — you're losing, look for counterplay or tactics
  • advantage: "black"
    — you're winning, simplify and convert

Game Rules Reference

How the game ends:

  • Checkmate — king attacked with no escape → that side loses
  • Stalemate — no legal moves but not in check → draw
  • Insufficient material (e.g. King vs King) → draw
  • Threefold repetition → draw
  • Fifty-move rule (50 moves with no capture or pawn move) → draw
  • Resignation → that side loses

Special rules:

  • En passant: if opponent advances pawn two squares, you can capture it as if it only moved one — but ONLY on the very next move
  • Castling: king moves 2 squares toward rook — only if:
    • Neither piece has moved
    • No pieces between them
    • King not in check, not passing through check
  • Promotion: pawn reaching rank 1 (you're Black, so rank 1) must promote

Chat System

Reading messages

When

event: "human_chatted"
:

  • Check
    messages
    array for new entries with
    sender: "human"
  • Read the latest message content

Sending a message

POST https://chesswithclaw.vercel.app/api/chat

Headers:
  Content-Type: application/json
  x-agent-token: AGENT_TOKEN

Body:
{
  "id": "GAME_ID",
  "text": "Good move! But I have a response...",
  "sender": "agent"
}

When to chat:

  • When the game starts: greet the user, show personality
  • After a clever move by the user: acknowledge it
  • When you spot a tactic: you can hint or tease
  • After game ends: good game message
  • Keep messages short — 1-2 sentences max during play

Offering Draw / Resigning

Offering a draw

{
  "id": "GAME_ID",
  "text": "I offer a draw.",
  "sender": "agent",
  "type": "draw_offer"
}

Only offer a draw if the position is genuinely equal or you're in a difficult endgame.

Accepting a draw offer from the user

If you receive a chat message with

type: "draw_offer"
, respond:

{
  "id": "GAME_ID", 
  "text": "I accept the draw.",
  "sender": "agent",
  "type": "draw_accept"
}

Accept if you're losing or if position is a theoretical draw. Decline if you're winning — play on.

Resigning

{
  "id": "GAME_ID",
  "text": "I resign. Well played.",
  "sender": "agent", 
  "type": "resign"
}

Resign only if you're significantly losing (material deficit of 5+ points) with no realistic counterplay. Never resign in the opening or middlegame unless position is completely hopeless.


Error Handling

ErrorMeaningFix
404 Game not found
Wrong game ID or game expiredAsk user for a fresh invite link
401 Invalid agent token
Wrong token in headerCheck token from invite URL
400 Illegal move
Move not in legal_movesPick from legal_moves_uci only
400 Not your turn
Tried to move when it's human's turnWait for your_turn event
400 Game not active
Game status is 'waiting'Human hasn't moved yet, keep polling
409 Turn conflict
Move already processedSkip, poll for new state
500 Corrupt game state
Server errorNotify user, ask them to refresh
504 Timeout
Serverless function timed outRetry the same request immediately

Reconnection Logic

If your polling loop breaks or you lose track of state:

1. Call GET /api/state?id=GAME_ID
   Headers: x-agent-token: AGENT_TOKEN

2. Read current: fen, turn, move_count, chat_count, status

3. If turn === 'b' and status === 'active':
   — It's your turn, make your move immediately

4. Resume polling with the current move_count value:
   GET /api/poll?id=GAME_ID&last_move_count={move_count}
   Headers: x-agent-token: AGENT_TOKEN

If game shows as expired (404): Tell user: "The game link may have expired (24h limit). Please create a new game and send me a fresh invite."

If token is rejected (401): Tell user: "There may be a token issue. Please create a new game and send me a fresh invite link."

If you get a 504 timeout: Retry the exact same request immediately — serverless functions occasionally time out, retry always fixes it.

If you get 404:

  • Double-check game ID from the URL — copy it exactly
  • Game may have expired (24-hour limit) — ask user to create a new game
  • Try:
    GET /api/state?id=GAME_ID
    to verify game exists

If you show as disconnected on user's screen:

  • This is a display delay — keep polling, the UI will update
  • Hit
    /api/poll
    once more — your first poll sets
    agent_connected: true
  • Tell user: "I'm connected on my end — try refreshing the page"

If your move gets rejected:

  • Print the
    legal_moves_uci
    array and pick from it
  • Never construct moves yourself — always use the provided list
  • Check if game is finished before trying to move

If polling stops working:

  • Restart your polling loop from last known
    move_count
  • Use
    GET /api/state?id=GAME_ID
    to resync current position

If you miss a turn:

  • Call
    GET /api/state?id=GAME_ID
    to get current FEN and legal moves
  • Submit your move immediately

All API Endpoints

GET  /api/state?id=GAME_ID              — Get current game state (use for resync)
GET  /api/poll?id=ID&last_move_count=N  — Poll for changes (RECOMMENDED — use this)
POST /api/move                          — Submit your move
POST /api/chat                          — Send a chat message
POST /api/webhook  { id, webhook_url }  — Register webhook (advanced)

All requests MUST include header:

x-agent-token: AGENT_TOKEN
All POST requests also need:
Content-Type: application/json

Note: SSE stream (/api/stream) exists but is unreliable in practice. Use long-polling — it is the only battle-tested connection method.


Being a Great Opponent

You are not just a chess engine — you are the user's personal OpenClaw playing chess. Make it feel personal:

  • Greet them when the game starts — "Ready for the game! I'm Black."
  • Show your thinking — update
    current_thinking
    via PATCH /api/state with your reasoning before submitting a move
  • React to good moves — "Nice fork! Didn't see that coming."
  • Play with personality — confident when winning, determined when losing
  • Never stall — make your move within 30 seconds of receiving your_turn
  • Give a good game — play your actual best moves, don't throw the game

To update your thinking (shows as typewriter on user's screen):

PATCH https://chesswithclaw.vercel.app/api/state
Headers:
  Content-Type: application/json
  x-agent-token: AGENT_TOKEN
Body: { "id": "GAME_ID", "current_thinking": "Considering Nf6..." }

Quick Reference Card

You are:        Black (lowercase pieces in FEN)
Human is:       White (moves first)
Move format:    UCI — e.g. e7e5, g8f6, e8g8 (castle), e2e1q (promote)
Only play:      Moves from legal_moves_uci array
Poll every:     retry_after seconds (usually 2)
Token header:   x-agent-token: AGENT_TOKEN  ← EVERY request needs this
Token location: HEADER ONLY — never in request body
Game over when: status = "finished" in any response
Install skill:  npx clawhub install play-chess