mcp-server-return-to-dark-tower
by ChessMess
README.md
> [!IMPORTANT]
> **This project has moved.** `mcp-server-return-to-dark-tower` is now part of the
> [UltimateDarkTower monorepo](https://github.com/ChessMess/UltimateDarkTower) at `apps/mcp-server`.
> Development continues there; this repository is **archived / read-only**.
> Full git history was preserved (tag `mcp-v1.0.0`).
>
> The npm package name is unchanged — `npx -y mcp-server-return-to-dark-tower` still works,
> and releases now ship from the monorepo.
# Return to Dark Tower — AI MCP Server
[](https://opensource.org/licenses/MIT)
[](https://nodejs.org/)
[](https://www.npmjs.com/package/mcp-server-return-to-dark-tower)
An MCP server that lets AI assistants like Claude, ChatGPT, and Gemini control the physical [Return to Dark Tower](https://restorationgames.com/return-to-dark-tower/) board game tower via Bluetooth. Connect, calibrate, play sounds, animate lights, rotate drums, break seals, and run dramatic game sequences — all through natural language.
### Features <!-- omit in toc -->
- **31 MCP tools** across 6 domains — connection, audio, lights, drums, seals, state & glyphs
- **15 tower state resources** — connection status, battery, drum positions, glyphs, seals, audio library, light effects
- **8 game knowledge resources** — rules, heroes, items, quests, adversaries, buildings, lore, glossary
- **8 prompt templates** — dramatic entrance, victory/defeat sequences, monthly transitions, dungeon runs, battle starts, game master setup, sound browser
- **Dual transport** — stdio for desktop AI tools, Streamable HTTP for web apps
- **Zero custom BLE code** — built on UltimateDarkTower adapter pattern
### AI Agents <!-- omit in toc -->
Ready-to-use AI agents for this server and the `ultimatedarktower` library:
👉 **[return-to-dark-tower-agents](https://github.com/ChessMess/return-to-dark-tower-agents)**
- **Return to Dark Tower agent** — system prompt for Claude.ai, ChatGPT, and other web AI tools; knows all 31 tools, 15 resources, and 8 prompts
- **Ultimate Dark Tower agent** — VS Code / GitHub Copilot coding agent for building apps with the `ultimatedarktower` npm library
Supported in VS Code (GitHub Copilot), Claude.ai, ChatGPT, and 20+ tools via the [AGENTS.md standard](https://agents.md).
---
## 📚 Table of Contents <!-- omit in toc -->
- [Return to Dark Tower — AI MCP Server](#return-to-dark-tower--ai-mcp-server)
- [⚡ Quick Start](#-quick-start)
- [🌐 For Web AI Chat Apps (Claude.ai, ChatGPT, etc.)](#-for-web-ai-chat-apps-claudeai-chatgpt-etc)
- [🖥️ For Desktop AI Tools (Claude Desktop, Cursor, VS Code, etc.)](#️-for-desktop-ai-tools-claude-desktop-cursor-vs-code-etc)
- [What is MCP?](#what-is-mcp)
- [Getting Started](#getting-started)
- [Prerequisites](#prerequisites)
- [Install](#install)
- [🖥️ Setup with Your AI Tool](#️-setup-with-your-ai-tool)
- [Claude Desktop](#claude-desktop)
- [🎯 Cursor](#-cursor)
- [🐙 VS Code (GitHub Copilot)](#-vs-code-github-copilot)
- [🌊 Windsurf](#-windsurf)
- [⚡ Zed](#-zed)
- [🔎 Perplexity (macOS App)](#-perplexity-macos-app)
- [🐋 DeepSeek](#-deepseek)
- [Summary](#summary)
- [🌐 Web-Based AI Chat Apps](#-web-based-ai-chat-apps)
- [Start the HTTP Server](#start-the-http-server)
- [Claude.ai (Web)](#claudeai-web)
- [ChatGPT / OpenAI](#chatgpt--openai)
- [Custom Web Applications](#custom-web-applications)
- [Available Tools](#available-tools)
- [Connection (8 tools)](#connection-8-tools)
- [Audio (3 tools)](#audio-3-tools)
- [Lights (5 tools)](#lights-5-tools)
- [Drums (4 tools)](#drums-4-tools)
- [Seals (5 tools)](#seals-5-tools)
- [State \& Glyphs (7 tools)](#state--glyphs-7-tools)
- [Available Resources](#available-resources)
- [Tower State Resources](#tower-state-resources)
- [Game Knowledge Resources](#game-knowledge-resources)
- [Glyph Icon Resources](#glyph-icon-resources)
- [Available Prompts](#available-prompts)
- [Architecture](#architecture)
- [CLI Options](#cli-options)
- [Dependencies](#dependencies)
- [Development](#development)
- [License](#license)
- [Acknowledgments](#acknowledgments)
---
## ⚡ Quick Start
> Requires [Node.js 18+](https://nodejs.org). Run `node --version` to check.
### 🌐 For Web AI Chat Apps (Claude.ai, ChatGPT, etc.)
**Step 1 — Open a terminal and start the server:**
```bash
npx -y mcp-server-return-to-dark-tower --http-only --port 3001
```
`npx` fetches the package from npm on first run (cached after that) and starts the server. **Keep this terminal open** — the server runs as long as the window is open.
**Step 2 — Connect your web AI app to the server.**
In your AI app's settings, add a new MCP connection pointing at:
```
http://localhost:3001/mcp
```
See [Web-Based AI Chat Apps](#-web-based-ai-chat-apps) for step-by-step instructions for Claude.ai and ChatGPT.
**Step 3 — Ask it something like:**
> _"Connect to the tower, calibrate it, then turn on all the north doorway lights."_
---
### 🖥️ For Desktop AI Tools (Claude Desktop, Cursor, VS Code, etc.)
**Step 1 — Add this to your AI tool's config file** (find the exact file path for your tool in [Setup with Your AI Tool](#️-setup-with-your-ai-tool)):
```json
{
"mcpServers": {
"return-to-dark-tower": {
"command": "npx",
"args": ["-y", "mcp-server-return-to-dark-tower", "--stdio-only"]
}
}
}
```
**Step 2 — Restart your AI tool.**
When it starts, it runs the `npx` command above — `npx` fetches the package from npm (first run only, cached after that) and launches the server as a background process. No separate terminal needed.
**Step 3 — Ask it something like:**
> _"Connect to the tower, calibrate it, then turn on all the north doorway lights."_
---
## What is MCP?
**MCP (Model Context Protocol)** is an open standard that lets AI assistants use tools and access data from external systems — similar to how a browser loads plugins. Instead of the AI just knowing about your tower, it can _control_ it.
This server implements the MCP standard. Once configured, your AI assistant gains 31 tools it can call by name — things like `tower_play_sound`, `tower_break_seal`, or `tower_rotate_drum` — and it can chain them together to run full dramatic game sequences on command.
**Two ways to connect:**
| Transport | Best for | How it works |
| --------- | ------------------------------------------------------- | ------------------------------------------------------------------------------------------ |
| **stdio** | Desktop AI apps (Claude Desktop, Cursor, VS Code, etc.) | The AI app launches this server as a background process and communicates over stdin/stdout |
| **HTTP** | Web-based AI apps (Claude.ai, ChatGPT web) | You start the server manually; the AI app connects to it over HTTP |
---
## Getting Started
### Prerequisites
Before you begin, make sure you have:
1. **Node.js 18 or newer** — Download from [nodejs.org](https://nodejs.org). To check your version, run `node --version` in a terminal.
2. **Bluetooth Low Energy (BLE) hardware** — Built into most Macs made after 2011 and most modern Windows PCs.
3. **A physical Return to Dark Tower tower**, though you could use the resources in the server without a tower.
**Platform-specific setup:**
| Platform | What you need to do |
| ----------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
| **macOS** | Nothing extra. After first use, grant Bluetooth permission: System Settings → Privacy & Security → Bluetooth → allow Terminal (or your AI app). |
| **Linux** | Install BlueZ first: `sudo apt install bluetooth bluez libbluetooth-dev` |
| **Windows** | Windows 10 or newer with Bluetooth is required. No extra setup needed. |
### Install
The easiest way is to use `npx`, which runs the package directly from npm without any installation step:
```bash
# Test that it works — this starts the server in stdio mode
npx -y mcp-server-return-to-dark-tower --stdio-only
```
> **What is `npx`?** It's a tool that comes bundled with Node.js. It downloads and runs a package from the [npm registry](https://npmjs.com) on demand, so you don't have to install anything globally.
If you'd rather install it globally (for faster startup after the first run):
```bash
npm install -g mcp-server-return-to-dark-tower
```
Pick your AI tool below for the exact config to paste in. You do **not** need to run the server yourself — your AI tool will start it for you using stdio.
<details>
<summary>Prefer to build from source?</summary>
```bash
git clone https://github.com/your-org/mcp-server-return-to-dark-tower.git
cd mcp-server-return-to-dark-tower
npm install
npm run build
```
Then in all config snippets below, replace:
```json
"command": "npx",
"args": ["-y", "mcp-server-return-to-dark-tower", "--stdio-only"]
```
with:
```json
"command": "node",
"args": ["/absolute/path/to/dist/index.js", "--stdio-only"]
```
</details>
---
## 🖥️ Setup with Your AI Tool
Each section is self-contained — jump straight to the tool you use.
All desktop AI tools use **stdio transport**. The config tells the AI app how to launch this server; the app handles the rest. You just edit a JSON (or YAML) config file, save it, and restart your AI app.
> **If the config file doesn't exist yet**, create it as a new empty file at the path shown. All configs shown below are complete and valid — you can paste them as-is if you're starting fresh.
>
> **If the file already exists**, add the `"return-to-dark-tower"` block inside the existing `"mcpServers"` (or equivalent) object. Don't replace the whole file.
---
### Claude Desktop
Claude Desktop reads its config file at startup. After saving changes, you must **fully quit and reopen** the app (⌘Q on Mac, not just closing the window).
**Config file location:**
| OS | Path |
| ------- | ----------------------------------------------------------------- |
| macOS | `~/Library/Application Support/Claude/claude_desktop_config.json` |
| Windows | `%APPDATA%\Claude\claude_desktop_config.json` |
> **Tip (macOS):** Open the file quickly in Terminal: `open -e ~/Library/Application\ Support/Claude/claude_desktop_config.json`
```json
{
"mcpServers": {
"return-to-dark-tower": {
"command": "npx",
"args": ["-y", "mcp-server-return-to-dark-tower", "--stdio-only"]
}
}
}
```
After restarting Claude, you should see a hammer icon (🔨) in the chat input area indicating MCP tools are available.
> **Windows note:** If `npx` doesn't work, try replacing `"command": "npx"` with `"command": "node"` and adding the full path to `node_modules/.bin/mcp-server-dark-tower.js` as the first arg, or install globally first.
---
### 🎯 Cursor
Cursor can load MCP config from a project-specific file or a global file.
**Config file locations:**
| Scope | Path |
| ----------------- | --------------------------------------------- |
| This project only | `.cursor/mcp.json` (in your project root) |
| All projects | `~/.cursor/mcp.json` (in your home directory) |
```json
{
"mcpServers": {
"return-to-dark-tower": {
"command": "npx",
"args": ["-y", "mcp-server-return-to-dark-tower", "--stdio-only"]
}
}
}
```
Cursor picks up changes automatically — no restart required.
> **Important:** MCP tools only appear when you're in **Agent mode**. In the Cursor chat panel, look for the mode selector and switch from "Normal" to "Agent" before asking the AI to use the tower.
---
### 🐙 VS Code (GitHub Copilot)
VS Code supports two config locations. The `.vscode/mcp.json` file can be committed to your repo so your whole team shares the same MCP setup.
> **Requires:** VS Code 1.99 or newer. Update via Help → Check for Updates.
**Option A — Workspace config** (recommended, shareable with your team):
Create or edit `.vscode/mcp.json` in your project root:
```json
{
"servers": {
"return-to-dark-tower": {
"type": "stdio",
"command": "npx",
"args": ["-y", "mcp-server-return-to-dark-tower", "--stdio-only"]
}
}
}
```
**Option B — User settings** (applies to all your projects):
Open `settings.json` (Cmd/Ctrl+Shift+P → "Open User Settings JSON") and add:
```json
{
"mcp": {
"servers": {
"return-to-dark-tower": {
"type": "stdio",
"command": "npx",
"args": ["-y", "mcp-server-return-to-dark-tower", "--stdio-only"]
}
}
}
}
```
> **Important:** Switch the Copilot Chat panel to **Agent mode** (look for the mode dropdown in the chat panel). MCP tools are not available in Ask or Edit modes.
---
### 🌊 Windsurf
Windsurf uses a single global config file for all MCP servers.
**Config file location:**
| OS | Path |
| ------------- | ------------------------------------------------- |
| macOS / Linux | `~/.codeium/windsurf/mcp_config.json` |
| Windows | `%USERPROFILE%\.codeium\windsurf\mcp_config.json` |
You can also open it from within Windsurf: click the **MCP icon** in the top-right of the Cascade panel → Configure.
```json
{
"mcpServers": {
"return-to-dark-tower": {
"command": "npx",
"args": ["-y", "mcp-server-return-to-dark-tower", "--stdio-only"]
}
}
}
```
Restart Windsurf after saving. The tower tools will appear in the **Cascade** agent panel.
---
### ⚡ Zed
Zed's MCP servers are configured in its global settings file.
**Config file location:**
| OS | Path |
| ------------- | ----------------------------- |
| macOS / Linux | `~/.config/zed/settings.json` |
| Windows | `%APPDATA%\Zed\settings.json` |
Add the `context_servers` block (alongside any existing settings in the file):
```json
{
"context_servers": {
"return-to-dark-tower": {
"source": "custom",
"command": "npx",
"args": ["-y", "mcp-server-return-to-dark-tower", "--stdio-only"],
"env": {}
}
}
}
```
Restart Zed after saving. Open the **Agent Panel** and look for a green dot next to the server name — that means it connected successfully.
---
### 🔎 Perplexity (macOS App)
Perplexity's native MCP support is available in the **Mac App** (download from the App Store). The web interface does not support MCP.
**Requirements:**
- macOS only
- Paid Perplexity plan (Pro or higher)
- The free tier does not include MCP
**Setup:**
1. Install the **Perplexity Mac App** from the App Store if you haven't already
2. Open the app and go to **Account Settings** → **Connectors**
3. Click **"Install Helper"** and install the **PerplexityXPC** helper app when prompted — this is a one-time step required by macOS's App Store sandbox rules
4. Click **"Add Connector"** → **Simple** → **"Add MCP Connector"**
5. Fill in:
- **Server Name:** `return-to-dark-tower` (or anything you like)
- **Command:** `npx`
- **Arguments:** `-y mcp-server-return-to-dark-tower --stdio-only`
6. Click **Save** and wait for the status indicator to show **Running**
7. In a Perplexity chat, click **Sources** and enable the `return-to-dark-tower` connector
There is no config file to edit — everything is done through Perplexity's UI.
> **Note:** Remote MCP support (for the web interface) is on Perplexity's roadmap but not yet available.
---
### 🐋 DeepSeek
DeepSeek's web chat (`chat.deepseek.com`) and API do not currently support MCP — there is no config file or UI to connect an MCP server to DeepSeek directly.
**If you're using DeepSeek through an IDE that supports it** (Cursor and VS Code both allow you to switch the underlying AI model to DeepSeek while keeping their MCP layer), MCP tools work fine. The IDE handles the MCP connection; it's independent of which AI model is powering the responses. Configure the tower using the [Cursor](#-cursor) or [VS Code](#-vs-code-github-copilot) section above, then switch your model to DeepSeek in that IDE's settings.
**If you use DeepSeek's own web or API interface**, MCP is not available at this time. Check [DeepSeek's documentation](https://platform.deepseek.com/docs) for updates.
---
### Summary
| Tool | Config file | Root key | Agent mode required? |
| ----------------- | ---------------------------- | ----------------- | ---------------------- |
| Claude Desktop | `claude_desktop_config.json` | `mcpServers` | No (always on) |
| Cursor | `.cursor/mcp.json` | `mcpServers` | **Yes** |
| VS Code (Copilot) | `.vscode/mcp.json` | `servers` | **Yes** |
| Windsurf | `mcp_config.json` | `mcpServers` | No (Cascade only) |
| Zed | `settings.json` | `context_servers` | No |
| Perplexity | App UI (no file) | — | macOS + paid plan only |
| DeepSeek | — | — | Not supported natively |
---
## 🌐 Web-Based AI Chat Apps
Web-based AI tools can't launch processes on your machine the way desktop apps can. Instead, you start the HTTP server yourself and point the web app at it.
### Start the HTTP Server
Open a terminal and run:
```bash
npx mcp-server-return-to-dark-tower --http-only --port 3001
```
**Keep this terminal window open** while you use your web AI tool. The server exposes:
- `http://localhost:3001/mcp` — the main MCP endpoint
- `http://localhost:3001/health` — returns `{"status":"ok"}` if it's running
To verify it's up, open [http://localhost:3001/health](http://localhost:3001/health) in your browser. You should see `{"status":"ok"}`.
> **What is `localhost`?** It means "this computer". The server is running on your machine and is only accessible from your own browser — it's not exposed to the internet by default.
---
### Claude.ai (Web)
Remote MCP connections are available on **Pro, Max, Team, and Enterprise** plans (not the free tier).
1. Go to [claude.ai](https://claude.ai) and open **Settings** → **Integrations**
2. Click **Add Integration** (or **Add MCP Server**)
3. Enter the URL: `http://localhost:3001/mcp`
4. Save. The tower tools will appear in your next conversation.
> **Heads up:** Claude.ai connects from your browser to `localhost`, which works as long as your browser and the server are on the same machine. If you want to use it from another device (like a phone), you'll need to expose the server publicly — see the note below.
<details>
<summary>Accessing from another device or sharing with others</summary>
Use a tunneling tool like [ngrok](https://ngrok.com) to create a public URL for your local server:
```bash
# In a second terminal (while the server is running)
ngrok http 3001
```
ngrok will print a public URL like `https://abc123.ngrok.io`. Use that URL instead of `http://localhost:3001` in your AI app's settings.
⚠️ Anyone with that URL can send commands to your tower. Use ngrok's auth features or keep the session short.
</details>
---
### ChatGPT / OpenAI
ChatGPT added MCP support in late 2025, available through **Developer Mode** (requires ChatGPT Plus or higher).
1. In ChatGPT, open **Settings** → **Developer Mode** (enable it if you haven't)
2. Go to **Connectors** → **Add Connector**
3. Select **Streamable HTTP** as the transport type
4. Enter the URL: `http://localhost:3001/mcp`
5. Save and start a new conversation. Tower tools will be available.
> **Note:** OpenAI's MCP UI is evolving quickly. If "Connectors" has been renamed to "Apps" or similar, look for the MCP integration option there. Check [OpenAI's help docs](https://help.openai.com) for the latest steps.
---
### Custom Web Applications
Building your own web app to control the tower? Use the HTTP endpoint directly.
**Start the server** with both transports running simultaneously:
```bash
npx mcp-server-return-to-dark-tower
# stdio on stdin/stdout + HTTP on http://localhost:3001/mcp
```
**Send a command with fetch:**
```javascript
// Generate a session ID once per user session
const sessionId = crypto.randomUUID();
const response = await fetch("http://localhost:3001/mcp", {
method: "POST",
headers: {
"Content-Type": "application/json",
"mcp-session-id": sessionId, // keeps this session's context consistent
},
body: JSON.stringify({
jsonrpc: "2.0",
id: 1,
method: "tools/call",
params: {
name: "tower_play_sound_by_name",
arguments: { name: "Ashstrider" },
},
}),
});
const result = await response.json();
console.log(result);
```
**Subscribe to streaming events (SSE):**
```javascript
const eventSource = new EventSource("http://localhost:3001/mcp");
eventSource.onmessage = (event) => {
const data = JSON.parse(event.data);
console.log("Tower event:", data);
};
```
> **CORS:** If your web app runs on a different port (e.g., `localhost:5173`), the browser will block requests to `localhost:3001` due to CORS. Configure your dev server to proxy `/mcp` requests, or add a CORS header to the MCP server. See the [Architecture](#architecture) section for details on how HTTP and stdio share a single tower connection.
---
## Available Tools
### Connection (8 tools)
| Tool | Description |
| ---------------------- | ------------------------------------------------- |
| `tower_connect` | Connect to the tower via BLE |
| `tower_disconnect` | Disconnect from the tower |
| `tower_calibrate` | Calibrate drum positions |
| `tower_status` | Get connection status, calibration state, battery |
| `tower_device_info` | Get manufacturer, model, firmware info |
| `tower_is_responsive` | Active connectivity check |
| `tower_cleanup` | Clean up resources |
| `tower_set_monitoring` | Configure connection monitoring |
### Audio (3 tools)
| Tool | Description |
| -------------------------- | ------------------------------------------------------ |
| `tower_play_sound` | Play a sound by index (1-113) |
| `tower_play_sound_by_name` | Play a sound by name (e.g., "Ashstrider") |
| `tower_list_sounds` | List available sounds, optionally filtered by category |
### Lights (5 tools)
| Tool | Description |
| ------------------------------ | ---------------------------------------------- |
| `tower_set_lights` | Set doorway, ledge, and base lights |
| `tower_set_led` | Set individual LED by layer and index |
| `tower_light_sequence` | Run a named light sequence by ID |
| `tower_light_sequence_by_name` | Run a light sequence by name (e.g., "victory") |
| `tower_lights_off` | Turn all lights off |
### Drums (4 tools)
| Tool | Description |
| -------------------------- | -------------------------------------- |
| `tower_rotate` | Rotate all drums to specific positions |
| `tower_rotate_drum` | Rotate a single drum to a position |
| `tower_random_rotate` | Randomly rotate drums |
| `tower_get_drum_positions` | Get current drum positions |
### Seals (5 tools)
| Tool | Description |
| ------------------------ | ----------------------------------------- |
| `tower_break_seal` | Break a seal at a specific side and level |
| `tower_is_seal_broken` | Check if a specific seal is broken |
| `tower_get_broken_seals` | Get all broken seals |
| `tower_reset_seals` | Reset all seals |
| `tower_random_seal` | Get a random unbroken seal |
### State & Glyphs (7 tools)
| Tool | Description |
| ------------------------- | ------------------------------- |
| `tower_get_state` | Get current tower state |
| `tower_send_state` | Send a tower state update |
| `tower_get_glyphs` | Get all glyph positions |
| `tower_get_glyph` | Get a specific glyph's position |
| `tower_glyphs_facing` | Get glyphs facing a direction |
| `tower_skull_count` | Get skull drop count |
| `tower_reset_skull_count` | Reset skull drop count |
---
## Available Resources
Resources are read-only data the AI can pull in for context (e.g., checking battery level before a long sequence).
### Tower State Resources
| Resource | URI | Description |
| ---------------- | ----------------------- | ------------------------------------------ |
| Tower Connection | `tower://connection` | Connection status, calibration, busy state |
| Device Info | `tower://device-info` | Manufacturer, model, firmware revisions |
| Battery | `tower://battery` | Millivolts, percentage, previous values |
| Drum Positions | `tower://drums` | All 3 drum positions |
| Glyph Positions | `tower://glyphs` | All 5 glyph positions and directions |
| Seal State | `tower://seals` | Broken/unbroken seals |
| Tower State | `tower://state` | Full tower state snapshot |
| Audio Library | `tower://audio-library` | All 113 sounds with categories |
| Light Effects | `tower://light-effects` | 6 effects + 19 named sequences |
### Game Knowledge Resources
| Resource | URI | Description |
| ----------- | -------------------------- | --------------------------------------- |
| Rules | `tower://game/rules` | Setup, turn phases, win/loss conditions |
| Adversaries | `tower://game/adversaries` | Abilities, spawn mechanics, escalation |
| Quests | `tower://game/quests` | Quest types, conditions, rewards |
| Items | `tower://game/items` | Equipment, potions, relics |
| Heroes | `tower://game/heroes` | Classes, stats, abilities |
| Buildings | `tower://game/buildings` | Citadel, sanctuary, village, bazaar |
| Lore | `tower://game/lore` | World lore, tower history, flavor |
| Glossary | `tower://game/glossary` | Key terms and concepts |
### Glyph Icon Resources
| Resource | URI | Description |
| ---------- | -------------------------- | ------------------- |
| Cleanse | `tower://glyphs/cleanse` | Cleanse glyph SVG |
| Quest | `tower://glyphs/quest` | Quest glyph SVG |
| Battle | `tower://glyphs/battle` | Battle glyph SVG |
| Banner | `tower://glyphs/banner` | Banner glyph SVG |
| Reinforce | `tower://glyphs/reinforce` | Reinforce glyph SVG |
| All Glyphs | `tower://glyphs/all` | Combined SVG sheet |
---
## Available Prompts
Prompts are pre-built instruction templates you can invoke by name. They chain multiple tools together into a single dramatic sequence.
| Prompt | Args | Description |
| -------------------- | ------------- | ------------------------------------------------------------ |
| `dramatic_entrance` | `adversary?` | Connect, calibrate, spawn sound, strobe lights, random drums |
| `victory_sequence` | `soundIndex?` | Victory sound + victory light sequence |
| `defeat_sequence` | — | Defeat sound + defeat lights |
| `monthly_transition` | `month?` | Month end/start sounds and lights |
| `dungeon_run` | `type?` | Dungeon sound + idle lights |
| `battle_start` | — | Battle sound + flicker lights |
| `game_master_setup` | — | Full game session setup guide |
| `sound_browser` | `category?` | Browse audio library by category |
---
## Architecture
```
┌─────────────────┐ ┌──────────────────┐
│ Claude Desktop │────▶│ stdio transport │──┐
└─────────────────┘ └──────────────────┘ │ ┌───────────────────┐ ┌─────────┐
├───▶│ TowerController │────▶│ Tower │
┌─────────────────┐ ┌──────────────────┐ │ │ (singleton) │ BLE │ (HW) │
│ React App │────▶│ HTTP transport │──┘ └───────────────────┘ └─────────┘
└─────────────────┘ └──────────────────┘
```
The `TowerController` singleton wraps `UltimateDarkTower` (v2.0.0) and is shared by both transports. The library's `BluetoothAdapterFactory` auto-detects the Node.js environment and uses `@stoprocent/noble` for BLE communication.
---
## CLI Options
| Flag | Description |
| -------------- | ----------------------------------------------- |
| `--stdio-only` | Run stdio transport only (for desktop AI tools) |
| `--http-only` | Run HTTP transport only (for web apps) |
| `--port <n>` | HTTP port (default: 3001) |
---
## Dependencies
| Package | Purpose |
| --------------------------- | ------------------------- |
| `@modelcontextprotocol/sdk` | MCP server and transport |
| `ultimatedarktower` | Tower BLE control library |
| `@stoprocent/noble` | Node.js BLE backend |
| `zod` | Schema validation |
| `express` | HTTP transport server |
---
## Development
```bash
npm run dev # Watch mode with tsx
npm run build # Compile TypeScript
npm run lint # Run ESLint + Prettier check
npm test # Run tests
```
---
## License
MIT — see [LICENSE](LICENSE).
---
## Acknowledgments
- [UltimateDarkTower](https://github.com/ChessMess/UltimateDarkTower) — the BLE library that makes this possible
- [Return to Dark Tower](https://restorationgames.com/return-to-dark-tower/) by Restoration Games
- The original [Dark Tower](<https://en.wikipedia.org/wiki/Dark_Tower_(game)>) (1981) by Milton Bradley
TDQS
A3.6/5.0
Scored across 34 tools
Disambiguation5/5
Each tool has a clearly distinct purpose, such as controlling lights, sounds, seals, or drums, with clear differentiation between similar tools like tower_play_sound and tower_play_sound_by_name.
Naming Consistency5/5
All tools follow a consistent tower_verb_noun pattern in snake_case, making it easy to predict tool names and understand their functions.
Tool Count3/5
With 34 tools, the set is large but justified by the complexity of controlling a physical device; however, it exceeds the typical well-scoped range of 3-15 and is near the 'too many' threshold.
Completeness5/5
The tool set covers all essential aspects of the device lifecycle: connection, calibration, state retrieval, light and sound control, seal management, drum rotation, and monitoring. No obvious gaps.
Maintenance
ActivitySlowing
ResponsivenessNo issues