mcp gameboy
A Model Context Protocol server that enables LLMs to interact with a GameBoy emulator, providing tools for controlling the GameBoy, loading ROMs, and retrieving screen frames.
A Model Context Protocol server that enables LLMs to interact with a GameBoy emulator, providing tools for controlling the GameBoy, loading ROMs, and retrieving screen frames.
A Model Context Protocol (MCP) server for serverboy, allowing LLMs to interact with a GameBoy emulator. Your LLM can... - Load ROMS - Press Keys - Look at the Gameboy Screen - skip frames
You can... - control the gameboy emulator using the @modelcontextprotocol/inspector - control the gameboy emulator (and upload ROMs) using a web-interface at http://localhost:3001/emulator - install the gameboy emulator in your favorite MCP-Client
To install GameBoy Emulator Server for Claude Desktop automatically via Smithery:
npx -y @smithery/cli install @mario-andreschak/mcp-gameboy --client claude
# Clone the repository
git clone https://github.com/yourusername/mcp-gameboy.git
cd mcp-gameboy
# Install dependencies
npm install
# Build the project
npm run build
!! ATTENTION : Many MCP Clients require to specify the ROM-Path in the .env vars as an absolute path
To integrate this MCP server with Cline or other MCP clients via configuration files:
Click "Edit in settings.json"
Add the server configuration to the mcpServers
object:
{
"mcpServers": {
"mcp-gameboy": {
"command": "node",
"args": [
"/path/to/mcp-gameboy/dist/index.js"
],
"disabled": false,
"autoApprove": []
}
}
}
Replace /path/to/mcp-gameboy/dist/index.js
with the actual path to the index.js
file in your project directory. Use forward slashes (/) or double backslashes () for the path on Windows.
Save the settings file. Cline should automatically connect to the server.
!! ATTENTION : Many MCP Clients require to specify the ROM-Path in the .env vars as an absolute path
Create a .env
file in the root directory with the following variables:
# Server configuration
PORT=3001
# ROM path for stdio mode
ROM_PATH=./roms/dangan.gb
In stdio mode, the server uses the ROM path specified in the ROM_PATH
environment variable. It will open a browser window to display the GameBoy screen.
npm run start
In SSE mode, the server starts an Express server that serves a web page for ROM selection.
npm run start-sse
Then open your browser to http://localhost:3001
to select a ROM.
The server provides the following tools:
press_up
: Press the UP button on the GameBoypress_down
: Press the DOWN button on the GameBoypress_left
: Press the LEFT button on the GameBoypress_right
: Press the RIGHT button on the GameBoypress_a
: Press the A button on the GameBoypress_b
: Press the B button on the GameBoypress_start
: Press the START button on the GameBoypress_select
: Press the SELECT button on the GameBoyload_rom
: Load a GameBoy ROM fileget_screen
: Get the current GameBoy screenAll tools return an ImageContent with the latest screen frame.
This server is built using the Model Context Protocol (MCP) TypeScript SDK. It uses:
McpServer
from @modelcontextprotocol/sdk/server/mcp.js
for the server implementationStdioServerTransport
from @modelcontextprotocol/sdk/server/stdio.js
for stdio transportSSEServerTransport
from @modelcontextprotocol/sdk/server/sse.js
for SSE transportserverboy
for the GameBoy emulationexpress
for the web server in SSE modecanvas
for rendering the GameBoy screenMIT
[
{
"description": "Press the UP button on the GameBoy",
"inputSchema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"additionalProperties": false,
"properties": {
"duration_frames": {
"default": 25,
"description": "Number of frames to hold the button",
"exclusiveMinimum": 0,
"type": "integer"
}
},
"type": "object"
},
"name": "press_up"
},
{
"description": "Press the DOWN button on the GameBoy",
"inputSchema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"additionalProperties": false,
"properties": {
"duration_frames": {
"default": 25,
"description": "Number of frames to hold the button",
"exclusiveMinimum": 0,
"type": "integer"
}
},
"type": "object"
},
"name": "press_down"
},
{
"description": "Press the LEFT button on the GameBoy",
"inputSchema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"additionalProperties": false,
"properties": {
"duration_frames": {
"default": 25,
"description": "Number of frames to hold the button",
"exclusiveMinimum": 0,
"type": "integer"
}
},
"type": "object"
},
"name": "press_left"
},
{
"description": "Press the RIGHT button on the GameBoy",
"inputSchema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"additionalProperties": false,
"properties": {
"duration_frames": {
"default": 25,
"description": "Number of frames to hold the button",
"exclusiveMinimum": 0,
"type": "integer"
}
},
"type": "object"
},
"name": "press_right"
},
{
"description": "Press the A button on the GameBoy",
"inputSchema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"additionalProperties": false,
"properties": {
"duration_frames": {
"default": 25,
"description": "Number of frames to hold the button",
"exclusiveMinimum": 0,
"type": "integer"
}
},
"type": "object"
},
"name": "press_a"
},
{
"description": "Press the B button on the GameBoy",
"inputSchema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"additionalProperties": false,
"properties": {
"duration_frames": {
"default": 25,
"description": "Number of frames to hold the button",
"exclusiveMinimum": 0,
"type": "integer"
}
},
"type": "object"
},
"name": "press_b"
},
{
"description": "Press the START button on the GameBoy",
"inputSchema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"additionalProperties": false,
"properties": {
"duration_frames": {
"default": 25,
"description": "Number of frames to hold the button",
"exclusiveMinimum": 0,
"type": "integer"
}
},
"type": "object"
},
"name": "press_start"
},
{
"description": "Press the SELECT button on the GameBoy",
"inputSchema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"additionalProperties": false,
"properties": {
"duration_frames": {
"default": 25,
"description": "Number of frames to hold the button",
"exclusiveMinimum": 0,
"type": "integer"
}
},
"type": "object"
},
"name": "press_select"
},
{
"description": "Wait for a specified number of frames",
"inputSchema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"additionalProperties": false,
"properties": {
"duration_frames": {
"default": 100,
"description": "Number of frames to wait",
"exclusiveMinimum": 0,
"type": "integer"
}
},
"type": "object"
},
"name": "wait_frames"
},
{
"description": "Load a GameBoy ROM file",
"inputSchema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"additionalProperties": false,
"properties": {
"romPath": {
"description": "Path to the ROM file",
"type": "string"
}
},
"required": [
"romPath"
],
"type": "object"
},
"name": "load_rom"
},
{
"description": "Get the current GameBoy screen (advances one frame)",
"inputSchema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"additionalProperties": false,
"properties": {},
"type": "object"
},
"name": "get_screen"
},
{
"description": "Check if a ROM is currently loaded in the emulator",
"inputSchema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"additionalProperties": false,
"properties": {},
"type": "object"
},
"name": "is_rom_loaded"
},
{
"description": "List all available GameBoy ROM files",
"inputSchema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"additionalProperties": false,
"properties": {},
"type": "object"
},
"name": "list_roms"
}
]