Skip to main content
Glama

Reconnaissance Blind Chess MCP Server

play_interactive.py4.59 kB
#!/usr/bin/env python3 """ Interactive RBC game player for Claude Code sessions. Plays a game and outputs JSON for easy parsing. """ import sys import json import chess import reconchess from io import StringIO class GameState: def __init__(self, color, opponent_bot_type='random'): self.board = chess.Board() self.color = color self.my_turn_count = 0 # Track what we know about the board self.known_board = chess.Board() for square in chess.SQUARES: self.known_board.remove_piece_at(square) # Place our own pieces (we can see them) for square in chess.SQUARES: piece = self.board.piece_at(square) if piece and piece.color == color: self.known_board.set_piece_at(square, piece) self.last_sense_result = None self.last_move_result = None self.opponent_move_result = None self.game_over = False self.winner = None def to_dict(self): return { "turn": self.my_turn_count, "color": "white" if self.color == chess.WHITE else "black", "board_fen": self.known_board.fen(), "game_over": self.game_over, "winner": self.winner, "last_sense_result": self.last_sense_result, "last_move_result": self.last_move_result, "opponent_move_result": self.opponent_move_result, } def print_board(board): """Print board in a nice format with coordinates.""" lines = [] lines.append(" +---+---+---+---+---+---+---+---+") for rank in range(7, -1, -1): row = f"{rank+1} |" for file in range(8): square = chess.square(file, rank) piece = board.piece_at(square) if piece: row += f" {piece.symbol()} |" else: row += " |" lines.append(row) lines.append(" +---+---+---+---+---+---+---+---+") lines.append(" a b c d e f g h") return "\n".join(lines) def square_to_name(square): """Convert square number to name like 'e4'.""" if square is None: return None return chess.square_name(square) def name_to_square(name): """Convert name like 'e4' to square number.""" if name.lower() == 'pass': return None try: return chess.parse_square(name) except: return None def format_sense_result(sense_result): """Format sense result as a readable grid.""" if not sense_result: return None lines = [] squares_dict = {sq: piece for sq, piece in sense_result} # Get the center square to determine the 3x3 grid center = sense_result[0][0] if sense_result else None if not center: return None center_file = chess.square_file(center) center_rank = chess.square_rank(center) lines.append(" +---+---+---+") for rank_offset in [1, 0, -1]: rank = center_rank + rank_offset if rank < 0 or rank > 7: continue row = " |" for file_offset in [-1, 0, 1]: file = center_file + file_offset if file < 0 or file > 7: row += " |" continue square = chess.square(file, rank) piece = squares_dict.get(square) if piece: row += f" {piece.symbol()} |" else: row += " |" lines.append(row) lines.append(" +---+---+---+") return "\n".join(lines) def main(): if len(sys.argv) < 2: print(json.dumps({"error": "Usage: play_interactive.py <command> [args...]"})) sys.exit(1) command = sys.argv[1] # For now, just implement a simple status command if command == "status": # This would load from a saved game state print(json.dumps({"status": "ready", "message": "Ready to start a new game"})) elif command == "start": color_arg = sys.argv[2] if len(sys.argv) > 2 else "white" color = chess.WHITE if color_arg.lower() == "white" else chess.BLACK bot_type = sys.argv[3] if len(sys.argv) > 3 else "random" state = GameState(color, bot_type) print(json.dumps({ "status": "game_started", "game_state": state.to_dict(), "board": print_board(state.known_board), "message": f"Game started! You are playing as {color_arg}." })) else: print(json.dumps({"error": f"Unknown command: {command}"})) if __name__ == "__main__": main()

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/FireKickerton/rbc-mcp-server'

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