npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

mcp-server-return-to-dark-tower

v1.0.0

Published

MCP server for controlling the Return to Dark Tower board game tower via Bluetooth

Downloads

115

Readme

Return to Dark Tower — AI MCP Server

License: MIT Node.js npm

An MCP server that lets AI assistants like Claude, ChatGPT, and Gemini control the physical 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

  • 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

📚 Table of Contents


⚡ Quick Start

Requires Node.js 18+. Run node --version to check.

🌐 For Web AI Chat Apps (Claude.ai, ChatGPT, etc.)

Step 1 — Open a terminal and start the server:

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 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):

{
  "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. 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:

# 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 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):

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.

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:

"command": "npx",
"args": ["-y", "mcp-server-return-to-dark-tower", "--stdio-only"]

with:

"command": "node",
"args": ["/absolute/path/to/dist/index.js", "--stdio-only"]

🖥️ 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

{
  "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) |

{
  "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:

{
  "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:

{
  "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.

{
  "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):

{
  "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 SettingsConnectors
  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 or VS Code 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 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:

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 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 and open SettingsIntegrations
  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.

Use a tunneling tool like ngrok to create a public URL for your local server:

# 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.


ChatGPT / OpenAI

ChatGPT added MCP support in late 2025, available through Developer Mode (requires ChatGPT Plus or higher).

  1. In ChatGPT, open SettingsDeveloper Mode (enable it if you haven't)
  2. Go to ConnectorsAdd 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 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:

npx mcp-server-return-to-dark-tower
# stdio on stdin/stdout  +  HTTP on http://localhost:3001/mcp

Send a command with fetch:

// 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):

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 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

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.


Acknowledgments