io.github.gunnargrosch/doom-mcp

Play DOOM via MCP - works with Claude Code, Cursor, and any MCP client

4MITdevtools

Install

Config snippet generator goes here (5 client tabs)

README

# DOOM via MCP

[![MCP Registry](https://img.shields.io/badge/MCP_Registry-published-blue)](https://registry.modelcontextprotocol.io)
[![npm version](https://img.shields.io/npm/v/doom-mcp)](https://www.npmjs.com/package/doom-mcp)
[![npm downloads](https://img.shields.io/npm/dm/doom-mcp)](https://www.npmjs.com/package/doom-mcp)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)

**Can it run DOOM? Yes - your AI coding assistant can run DOOM.**

Play DOOM in Claude Code, Cursor, or any MCP-compatible client. The AI sees the game, fights demons, navigates levels, and reports what's happening - or you direct it move by move.

```
> Let's play DOOM!

  Starting E1M1 on medium difficulty...

  HP:100 Armor:0 | Pistol (key:2) | Ammo: 50b 0s 0r 0c | Kills:0 | E1M1
  No enemies in sight. Exploring the corridor ahead.

> Go forward and find some enemies

  Sprinting down the hallway... I can see an opening ahead.

  HP:100 Armor:0 | Pistol (key:2) | Ammo: 50b 0s 0r 0c | Kills:0 | E1M1
  ENEMIES IN SIGHT (aim for angle~0 then fire): Imp (HP:60) to your left (turn_left ~9) nearby

  There's an Imp to the left! Turning to face it...

> Shoot it!

  Aimed and firing!

  HP:100 Armor:0 | Pistol (key:2) | Ammo: 47b 0s 0r 0c | Kills:0 | E1M1
  ENEMIES IN SIGHT (aim for angle~0 then fire): Imp (HP:15) AHEAD close

  Hit! The Imp is wounded (HP:15). One more burst should finish it.

  HP:95 Armor:0 | Pistol (key:2) | Ammo: 44b 0s 0r 0c | Kills:1 | E1M1
  ITEMS: Stimpack (+10 HP) slightly to your right (turn_right ~4) point-blank (~3 ticks fwd+run to reach)
  1 kill! Want to see a screenshot?
```

Read the [blog post](https://dev.to/gunnargrosch/can-it-run-doom-playing-doom-in-claude-code-with-doom-mcp-1ck1) for the full story.

---

## Table of Contents

- [How It Works](#how-it-works)
- [Quick Start](#quick-start)
- [Play Modes](#play-modes)
- [Tools Reference](#tools-reference)
- [Configuration](#configuration)
- [FAQ](#faq)
- [Architecture](#architecture)
- [Development](#development)
- [Credits](#credits)
- [License](#license)

---

## How It Works

A Rust MCP server embeds the real DOOM engine (doomgeneric) directly via FFI. No emulation, no child processes. Each tool call advances the game by a number of ticks and returns:

1. **Game state** - HP, armor, ammo, kills, position, current weapon
2. **Enemy intel** - visible enemies with human-readable direction, distance, and HP
3. **Nearby items** - health, ammo, armor, weapons within pickup range
4. **Doors and switches** - interactable linedefs detected within range
5. **Frame image** - small PNG thumbnail for the AI's vision

The AI uses this information to navigate, fight, and explore. You can direct it or let it play autonomously.

```mermaid
graph LR
    A[MCP Client] -->|doom_start| B[doom-mcp binary]
    A -->|doom_action| B
    A -->|doom_screenshot| B
    B -->|FFI| C[doomgeneric C engine]
    C -->|frame buffer| B
    B -->|game state + PNG| A
```

---

## Quick Start

### 1. Register with your MCP client

**Claude Code:**

```sh
claude mcp add doom --scope user -- npx -y doom-mcp
```

**Cursor, Windsurf, or any MCP client** - add to `.mcp.json`:

```json
{
  "mcpServers": {
    "doom": {
      "type": "stdio",
      "command": "npx",
      "args": ["-y", "doom-mcp"]
    }
  }
}
```

### 2. Play

Open a new session and say:

> "Let's play DOOM"

The AI will ask which mode you want, start the game on E1M1, and begin playing.

---

## Play Modes

| Mode | How it works | Best for |
|------|-------------|----------|
| **You direct** | You give commands ("go forward", "open that door", "shoot the imp"). The AI executes one action at a time and describes what happens. | Immersive guided play |
| **AI autonomous** | The AI makes all decisions - movement, combat, exploration. You watch and intervene if needed. | Watching the AI play |

---

## Tools Reference

### doom_start

Start or restart DOOM. Safe to call at any time — if a game is already running it restarts cleanly without needing a new session.

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `skill` | int (1-5) | 3 | Difficulty: 1=baby, 2=easy, 3=medium, 4=hard, 5=nightmare |
| `episode` | int (1-4) | 1 | Episode number |
| `map` | int (1-9) | 1 | Map number |

### doom_action

Advance the game. All listed actions are held simultaneously for the tick duration.

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `actions` | string | yes | Comma-separated: `forward`, `backward`, `turn_left`, `turn_right`, `strafe_left`, `strafe_right`, `fire`, `use`, `run`, `1`-`7` |
| `ticks` | int (1-105) | no | Game ticks to advance. Default 7. At 35 ticks/sec: 7 ~ 0.2s, 35 ~ 1s |

**Gameplay notes:**
- `fire` holds the trigger for the full duration. Pistol auto-fires every ~10 ticks.
- Turn and fire should be separate actions (turning while firing wastes ammo).
- `use` opens doors and activates switches.
- Weap