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

mudsplatjs

v1.0.0

Published

Telnet+GMCP+MCCP to WebSocket proxy for MUD clients

Readme

MUDSplat.js

npm license

Telnet+GMCP+MCCP+MXP to WebSocket proxy for MUD clients. Play any MUD from a browser, build bots, or pipe structured game data into your own frontend.

┌─────────────┐     WebSocket      ┌─────────────┐      Telnet       ┌──────────┐
│   Browser /  │◄──────────────────►│  MudProxy   │◄────────────────►│   MUD    │
│   xterm.js   │   JSON messages    │  (Node.js)  │  GMCP+MCCP+MXP   │  Server  │
└─────────────┘                     └─────────────┘                   └──────────┘

Install

npm install mudsplatjs
# or
pnpm add mudsplatjs

What is this?

MUDSplat.js handles the gnarly parts of connecting to a MUD — telnet negotiation, GMCP structured data, MCCP2 compression, and MXP rich text — so you can focus on building your client or bot. It gives you two ways in:

  1. Web client: Run the proxy server, connect from your browser via WebSocket. ANSI escape codes are passed through raw so xterm.js renders them natively. GMCP and MXP arrive as parsed JSON.
  2. Bot / script: Use MudConnection directly from Node.js. No proxy needed.

Building a Web Client

You need two pieces: a proxy server (Node.js) and a browser client.

1. Create your proxy server

// server.js
const { MudProxy } = require('mudsplatjs');

const proxy = new MudProxy({ port: 8080 });

proxy.on('listening', ({ port }) => {
  console.log(`MUDSplat proxy on port ${port}`);
});

proxy.start();
node server.js

2. Connect from your browser

The package includes a browser client at mudsplatjs/client. For a typical xterm.js setup:

<script src="node_modules/mudsplatjs/src/client.js"></script>
<script src="https://cdn.jsdelivr.net/npm/xterm/lib/xterm.min.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/xterm/css/xterm.min.css">

<div id="terminal"></div>

<script>
  const terminal = new Terminal();
  terminal.open(document.getElementById('terminal'));

  const mud = new MudSplatClient('ws://localhost:8080');

  // ANSI output goes straight to xterm.js — colors, bold, etc. just work
  mud.on('output', (text) => terminal.write(text));

  // Structured game data via GMCP
  mud.on('gmcp', (name, data) => {
    if (name === 'Char.Vitals') updateHealthBar(data);
    if (name === 'Room.Info') updateMap(data);
  });

  // Clickable MXP elements (exits, items, etc.)
  mud.on('mxp', (elements) => {
    for (const el of elements) {
      if (el.type === 'send') renderClickable(el.text, el.command);
    }
  });

  // Connect to a MUD
  await mud.connect('aardmud.org', 4000);

  // Send commands from user input
  terminal.onData((text) => mud.send(text));
</script>

The proxy talks JSON over WebSocket. Your client sends commands like { "type": "input", "text": "look" } and receives output, GMCP, MXP, and status events. See the full WebSocket protocol below.

Building a Bot or Script

Skip the proxy — connect to a MUD directly from Node.js:

const { MudConnection } = require('mudsplatjs');

const mud = new MudConnection({
  host: 'aardmud.org',
  port: 4000,
  gmcpPackages: ['Core 1', 'Char 1', 'Room 1'],
});

// Raw text output (including ANSI codes)
mud.on('data', (text) => process.stdout.write(text));

// Structured data — no need to parse text
mud.on('gmcp', ({ name, data }) => {
  if (name === 'Char.Vitals') {
    console.log(`HP: ${data.hp}/${data.maxhp}`);
  }
});

mud.on('close', () => {
  console.log('Disconnected');
  process.exit(0);
});

await mud.connect();
mud.send('look');

If you need to strip ANSI for logging or plain-text processing:

const { stripAnsi } = require('mudsplatjs');

mud.on('data', (text) => {
  fs.appendFileSync('mud.log', stripAnsi(text));
});

Features

  • WebSocket proxy — bridge any telnet MUD to WebSocket clients with a JSON protocol
  • GMCP — structured game data: vitals, room info, inventory, channels, skills
  • MCCP2 — transparent zlib decompression of compressed MUD streams
  • MXP — clickable commands, links, and rich text elements parsed into structured data
  • ANSI passthrough — raw escape codes forwarded untouched for xterm.js / terminal rendering
  • Direct connectionsMudConnection class for server-side bots and scripts
  • Browser client — lightweight MudSplatClient for frontend apps
  • Host whitelisting — restrict which MUDs the proxy can connect to
  • TypeScript definitions included

WebSocket Protocol

All messages are JSON with a type field.

Client to Proxy

| Type | Fields | Description | |------|--------|-------------| | connect | host, port, gmcpPackages? | Open a MUD connection | | input | text | Send a command (newline added automatically) | | gmcp | name, data? | Send a GMCP message | | disconnect | — | Close the MUD connection |

Proxy to Client

| Type | Fields | Description | |------|--------|-------------| | output | text | Raw text from the MUD (with ANSI escape codes) | | gmcp | name, data | Parsed GMCP message | | mxp | elements, mode | Parsed MXP elements (send, link, formatting) | | prompt | text | Prompt detected (via Telnet GA) | | connected | host, port | MUD connection established | | disconnected | — | MUD connection closed | | mccp | active | Compression state changed | | error | message | Error |

Proxy Options

new MudProxy({
  port: 8080,             // WebSocket port
  host: '0.0.0.0',       // Bind address
  allowedHosts: [],       // MUD host whitelist (empty = allow all)
  maxConnections: 100,    // Max simultaneous connections
  gmcp: true,             // Enable GMCP
  mccp: true,             // Enable MCCP2
  mxp: true,              // Enable MXP
});

Documentation

Full API reference, protocol docs, and GMCP/MCCP/MXP guides: lazerthings.github.io/mudsplatjs

License

Apache-2.0