Skip to main content
Glama

Texas Holdem MCP Server

by freshlife001
PokerServer.ts9.06 kB
import { Player, PlayerAction } from '../models/Player'; import { GameManager } from './GameManager'; export interface PokerRequest { method: string; params: any; id: string | number; } export interface PokerResponse { result?: any; error?: { code: number; message: string; }; id: string | number; } export class PokerServer { private gameManager: GameManager; private players: Map<string, Player> = new Map(); constructor(gameManager: GameManager) { this.gameManager = gameManager; } handleRequest(request: PokerRequest): PokerResponse { console.log(`[PokerServer] Received request: ${JSON.stringify(request)}`); try { const { method, params, id } = request; switch (method) { case 'register': return this.logResponse(this.handleRegister(params, id)); case 'createTable': return this.logResponse(this.handleCreateTable(params, id)); case 'listTables': return this.logResponse(this.handleListTables(params, id)); case 'joinTable': return this.logResponse(this.handleJoinTable(params, id)); case 'leaveTable': return this.logResponse(this.handleLeaveTable(params, id)); case 'getTableState': return this.logResponse(this.handleGetTableState(params, id)); case 'performAction': return this.logResponse(this.handlePerformAction(params, id)); default: return this.logResponse({ error: { code: -32601, message: `Method '${method}' not found` }, id }); } } catch (error) { const response = { error: { code: -32603, message: error instanceof Error ? error.message : 'Internal error' }, id: request.id }; console.error(`[PokerServer] Error processing request: ${error}`); return this.logResponse(response); } } // Helper method to log responses private logResponse(response: PokerResponse): PokerResponse { // For large responses (like table state), we might want to limit what we log const logSafeResponse = { ...response }; if (logSafeResponse.result && typeof logSafeResponse.result === 'object') { // Truncate large result objects for logging logSafeResponse.result = '(Result object - see full response for details)'; } console.log(`[PokerServer] Sending response: ${JSON.stringify(logSafeResponse)}`); return response; } private handleRegister(params: any, id: string | number): PokerResponse { const { name, chips } = params; if (!name) { return { error: { code: -32602, message: 'Invalid params: name is required' }, id }; } // Check if a player with this name already exists let existingPlayer: Player | undefined; for (const player of this.players.values()) { if (player.name === name) { existingPlayer = player; break; } } if (existingPlayer) { // Return the existing player instead of creating a new one console.log(`Player with name ${name} already exists, returning existing player`); return { result: { playerId: existingPlayer.id, name: existingPlayer.name, chips: existingPlayer.chips }, id }; } // Create a new player if no existing player was found const playerId = `player_${Date.now()}_${Math.floor(Math.random() * 1000)}`; const initialChips = chips || 1000; const player = new Player(playerId, name, initialChips); this.players.set(playerId, player); return { result: { playerId, name, chips: initialChips }, id }; } private handleCreateTable(params: any, id: string | number): PokerResponse { const { name, smallBlind, bigBlind, maxPlayers } = params; if (!name) { return { error: { code: -32602, message: 'Invalid params: name is required' }, id }; } const table = this.gameManager.createTable( name, smallBlind || 5, bigBlind || 10, maxPlayers || 9 ); return { result: { tableId: table.id, name: table.name, smallBlind: table.smallBlind, bigBlind: table.bigBlind, maxPlayers: table.maxPlayers }, id }; } private handleListTables(params: any, id: string | number): PokerResponse { const tables = this.gameManager.getAllTables(); return { result: tables.map(table => ({ id: table.id, name: table.name, players: table.players.length, maxPlayers: table.maxPlayers, smallBlind: table.smallBlind, bigBlind: table.bigBlind, stage: table.stage })), id }; } private handleJoinTable(params: any, id: string | number): PokerResponse { const { playerId, tableId } = params; if (!playerId || !tableId) { return { error: { code: -32602, message: 'Invalid params: playerId and tableId are required' }, id }; } const player = this.players.get(playerId); if (!player) { return { error: { code: -32602, message: `Player with ID ${playerId} not found` }, id }; } const success = this.gameManager.joinTable(tableId, player); if (!success) { return { error: { code: -32603, message: `Failed to join table ${tableId}` }, id }; } return { result: { success: true, tableId, playerId }, id }; } private handleLeaveTable(params: any, id: string | number): PokerResponse { const { playerId } = params; if (!playerId) { return { error: { code: -32602, message: 'Invalid params: playerId is required' }, id }; } const success = this.gameManager.leaveTable(playerId); return { result: { success }, id }; } private handleGetTableState(params: any, id: string | number): PokerResponse { const { tableId, playerId } = params; if (!tableId) { return { error: { code: -32602, message: 'Invalid params: tableId is required' }, id }; } const table = this.gameManager.getTable(tableId); if (!table) { return { error: { code: -32602, message: `Table with ID ${tableId} not found` }, id }; } // Create a view of the table state // If playerId is provided, include the player's cards const tableState = { id: table.id, name: table.name, stage: table.stage, pot: table.pot, currentBet: table.currentBet, smallBlind: table.smallBlind, bigBlind: table.bigBlind, communityCards: table.communityCards.map(card => card.toString()), players: table.players.map(p => { const playerView = { id: p.id, name: p.name, chips: p.chips, bet: p.bet, folded: p.folded, isAllIn: p.isAllIn, isDealer: p.isDealer, isSmallBlind: p.isSmallBlind, isBigBlind: p.isBigBlind, isActive: p.isActive, hand: p.id === playerId ? p.hand.map(card => card.toString()) : [] }; return playerView; }), currentPlayerIndex: table.currentPlayerIndex }; return { result: tableState, id }; } private handlePerformAction(params: any, id: string | number): PokerResponse { const { playerId, action, amount } = params; if (!playerId || !action) { return { error: { code: -32602, message: 'Invalid params: playerId and action are required' }, id }; } // Validate action const validActions = Object.values(PlayerAction); if (!validActions.includes(action as PlayerAction)) { return { error: { code: -32602, message: `Invalid action: ${action}. Valid actions are: ${validActions.join(', ')}` }, id }; } const success = this.gameManager.performAction(playerId, action, amount || 0); if (!success) { return { error: { code: -32603, message: 'Failed to perform action' }, id }; } // Get updated table state const table = this.gameManager.getPlayerTable(playerId); return { result: { success: true, tableState: table ? table.toJSON(): null }, id }; } }

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/freshlife001/mcp_poker'

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