A minimal MCP (Model Context Protocol) server that manages the state of text adventure games. Built with Python, FastMCP, Redis, and FastAPI.
- MCP Server: Exposes game actions as MCP tools for LLM interaction
- Multiple Transport Protocols: Supports both stdio and streamable-http transports
- Redis State Management: Persistent game state storage
- Web Dashboard: Real-time game state monitoring
- Docker Support: Easy deployment with Docker Compose
- Zork-style Gameplay: Classic text adventure mechanics
state-of-play/
├── src/
│ ├── main.py # MCP server entry point
│ ├── game_engine.py # Core game logic
│ ├── state_manager.py # Redis state management
│ ├── web_interface.py # FastAPI web server
│ └── models/
│ ├── game_state.py # Game state models
│ └── entities.py # Room, Item, NPC models
├── config/
│ └── game_config.json # Game scenario configuration
├── docker-compose.yml
├── Dockerfile
└── requirements.txt
- Clone the repository:
git clone <repository-url>
cd state-of-play- Start the services:
docker-compose up -d-
Access the web dashboard at
http://localhost:8000 -
Access the MCP server over HTTP at
http://localhost:8001/mcp -
To run different server modes:
# MCP server with stdio transport (for local LLM clients)
RUN_MODE=mcp python -m src.main
# MCP server with HTTP transport (for remote LLM clients)
RUN_MODE=mcp-http python -m src.main
# All servers (web + MCP HTTP)
RUN_MODE=all python -m src.main- Install Redis:
# Ubuntu/Debian
sudo apt install redis-server
# macOS
brew install redis- Start Redis:
redis-server- Install Python dependencies:
pip install -r requirements.txt- Run the web server:
python -m src.mainRun different MCP server modes:
# MCP with stdio transport (local clients)
RUN_MODE=mcp python -m src.main
# MCP with HTTP transport (remote clients)
RUN_MODE=mcp-http python -m src.main
# All servers together
RUN_MODE=all python -m src.mainThe server exposes these MCP tools for LLM interaction:
move_player(direction)- Move in a direction (north, south, east, west, up, down)look_around()- Get current room descriptiontake_item(item_name)- Take an item from the current roomdrop_item(item_name)- Drop an item into the current roomuse_item(item_name, target)- Use an item, optionally on a targettalk_to_npc(npc_name, message)- Talk to an NPCcheck_inventory()- List player's inventoryget_available_actions()- Get context-aware action listget_game_status()- Get current game state summarystart_new_game(player_name)- Start a new gameend_game()- End game and generate summary
Games are configured via config/game_config.json. The included example features:
- Setting: Mysterious laboratory escape room
- Objective: Find and assemble the master key to escape
- Mechanics: Item collection, NPC dialogue, puzzle solving
- Rooms: Laboratory entrance, main lab, storage room, secure vault
- Items: Key cards, power cells, tools, key fragments
- NPCs: Helpful scientist with dialogue tree
The web interface at http://localhost:8000 provides:
- Real-time game state visualization
- Interactive room map with player location
- Inventory and item tracking
- Event log with game history
- Game reset functionality
- Auto-refreshing display (every 5 seconds)
Game state is stored in Redis with these key patterns:
game:{game_id}:state- Complete game state JSONgame:{game_id}:rooms- Room data hashgame:{game_id}:items- Item data hashgame:{game_id}:npcs- NPC data hashgame:{game_id}:players- Player data hashgame:{game_id}:logs- Chronological event listgame:{game_id}:flags- Global game flags
REDIS_URL- Redis connection URL (default:redis://localhost:6379)MCP_PORT- MCP HTTP server port (default:8001)WEB_PORT- Web interface port (default:8000)RUN_MODE- Server mode:web(default),mcp,mcp-http,combined, orall
web- Web dashboard only (default)mcp- MCP server with stdio transport (for local clients)mcp-http- MCP server with streamable-http transport (for remote clients)combined- Web dashboard + MCP stdioall- Web dashboard + MCP HTTP server
# Default: web dashboard only
docker-compose up
# MCP HTTP server only
docker-compose --profile mcp-only up mcp-server
# Web dashboard + MCP HTTP server
docker-compose --profile all-services up all-servers# Install test dependencies
pip install pytest pytest-asyncio
# Run tests
pytestThe project follows PEP 8 and uses type hints throughout. Format code with:
pip install black isort
black .
isort .Edit config/game_config.json and add room objects with:
- Unique
id - Descriptive
nameanddescription connectionsto other roomsitemsandnpcslists- Optional
access_requirements
Items support:
takeableanduseableflags- Custom
properties use_effectsfor game state changes- Location tracking (room, player, or NPC)
NPCs feature:
- Dialogue trees with state transitions
- Inventory management
- Location-based interactions
GET /- Game dashboard HTMLGET /api/state- Current game state JSONGET /api/logs- Game event history JSONPOST /api/reset- Reset game to initial state
See src/game_engine.py for the complete API including:
- Player movement and actions
- Item manipulation
- NPC interactions
- State persistence
- Event logging
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests for new functionality
- Submit a pull request
MIT License - see LICENSE file for details.
For issues and questions:
- Check the GitHub issues page
- Review the configuration examples
- Examine the web dashboard for state debugging