What is a module?
Abstractly speaking, a module is something with an inside and an outside.
In design, a system is broken down into modules which can then be implemented separately. Modules and their boundaries are carefully chosen so that the stuff inside goes together, and the boundary is well-defined and minimal. These two properties are called cohesion and coupling, respectively. A system may or may not require a module, a system may allow only one instance of a module or it may allow any number of instances. A module is usually drawn with a box symbol. The boundary that separates inside from outside is also called its interface.
Module boundaries may be physical as we see with pins on a chip, a USB cable, or a video card; modules boundaries may be compile-time as we see with ./configure switches or platform gloss; or, modules may be run-time as we see between operating systems, the applications they run, and all the other supporting, cooperating processes.
So, obviously, the term module is overused and probably over-general.
What is a module in MUSH?
In the context of a MUSH server, modules are usually separately-compiled pieces of code which are loaded by the main server. There is a run-time boundary between the module and the main server. One of the purposes of defining a module interface was to support an alternative way for someone other than the server maintainer to add some low-level code to the server without patching the server. So, the purpose was primarily organizational -- the desire to allow multiple teams to proceed more-or-less independently.
However, the kinds of code, range of possible new or altered behaviors, and degree of independence between modules and the main server retains one very large dependency -- the definition of the module interface itself. It's the one thing that is not allowed to change.
What module interfaces are available?
PennMUSH and TinyMUX provide a local.c/cpp patching surface that essentially provides a compile-time module interface. However, only one module at a time is supported by this. RhostMUSH also uses this method, though supports the addition of more than one module at a time.
TinyMUSH 3.1 and later include a method of using externally loadable modules. This particular method is something like a low-level hook sytem that allows separate code to be notified when certain server functions are called or to replace certain functions. There is only one rigidly-defined interface, and it is between the main server and the individual module. Individual modules can define their own APIs and make the server aware of them, allowing cross-module communication. For instance, the most recent versions of the freely available 'email' module for TinyMUSH define an email API, which other modules can then use to send e-mail. This functionality has not been widely utilized, however.
TinyMUX 2.7 and later have a dynamic module interface; this implementation is a poor man's version of the Component Object Model (COM) found on Windows. Any number of interfaces can be defined and it is not necessary for the main server to be aware of them.
RhostMUSH includes a module interface called @doors. This implements an internal/external TCP/IP bridge between the mush and outside applications/connections. Rhost developers are also reportedly working on a @plugin command and system; though still in the design phase, the intent is to allow a semi-standard method by which one can dynamically load and unload subsystems on the fly.
What modules are available?
The short answer is 'not many'. The most successful module interface so far is the local.c/cpp patching surface. Existing add-ins are written to use that, and there is some inertia against changing something that works.