Rmcp Mux
mcp servers multiplexer for stdio
Ask AI about Rmcp Mux
Powered by Claude Β· Grounded in docs
I know everything about Rmcp Mux. Ask me about installation, configuration, usage, or troubleshooting.
0/500
Reviews
Documentation
rmcp-mux β MCP Server Multiplexer
A Rust daemon that manages all your MCP servers from a single process. Define servers in mux.toml, run one rmcp-mux command, and get Unix sockets for each service. Features ID rewriting, initialize caching, auto-restart, and an interactive TUI dashboard.
NEW in 0.3.x: Unified process model with daemon status socket! One rmcp-mux process manages all servers from config file. Interactive TUI dashboard for monitoring and control. Query live status via rmcp-mux daemon-status.
Table of Contents
- Features
- Quick Start
- Installation
- Configuration
- CLI Reference
- Interactive TUI Dashboard
- Library Usage
- Runtime Behavior
- Project Structure
- Testing
- Contributing
Features
Core
- Single process, multiple servers β one
rmcp-muxmanages all MCP servers defined in config - Unix socket per service β each server gets its own socket for client connections
- ID rewriting β responses matched to correct client across all services
- Initialize caching β executed once per server; cached response served to subsequent clients
- Auto-restart β servers restart on failure with exponential backoff
- Graceful shutdown β Ctrl+C stops all servers, removes sockets
Monitoring & Control
- Interactive TUI (
--tui) β real-time dashboard with server status, restart controls - Status command (
--show-status) β JSON snapshot of all server states - Per-server control β restart, stop, start individual servers at runtime
- Selective startup β
--onlyand--exceptflags for partial launches
Configuration
- TOML config β simple, readable server definitions
- Environment variables β per-server env injection
- Flexible parameters β timeouts, client limits, restart policies
Quick Start
# 1. Create config file
cat > mux.toml << 'EOF'
[servers.memory]
socket = "/tmp/mcp-memory.sock"
cmd = "npx"
args = ["-y", "@modelcontextprotocol/server-memory"]
[servers.filesystem]
socket = "/tmp/mcp-fs.sock"
cmd = "npx"
args = ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"]
EOF
# 2. Start all servers
rmcp-mux --config mux.toml
# 3. Or start with TUI dashboard
rmcp-mux --config mux.toml --tui
# 4. Connect via proxy (for MCP hosts expecting STDIO)
rmcp-mux-proxy --socket /tmp/mcp-memory.sock
Installation
From source
cargo build --release
# Binaries: target/release/rmcp-mux, target/release/rmcp-mux-proxy
One-liner (curl | sh)
curl -fsSL https://raw.githubusercontent.com/Loctree/rmcp-mux/main/tools/install.sh | sh
Environment overrides:
INSTALL_DIRβ wrapper location (default:$HOME/.local/bin)CARGO_HOMEβ cargo home (default:~/.cargo)MUX_REFβ branch/tag/commit (default:main)MUX_NO_LOCK=1β skip--lockedflag
Built-in proxy
If your MCP host needs a STDIO command, use the bundled proxy:
rmcp-mux-proxy --socket /tmp/mcp-memory.sock
Configuration
Config file format (TOML)
[servers.memory]
socket = "~/mcp-sockets/memory.sock"
cmd = "npx"
args = ["-y", "@modelcontextprotocol/server-memory"]
max_active_clients = 5
tray = true
[servers.brave-search]
socket = "~/mcp-sockets/brave.sock"
cmd = "npx"
args = ["-y", "@anthropic/mcp-server-brave-search"]
env = { BRAVE_API_KEY = "your-api-key" }
request_timeout_ms = 60000
[servers.filesystem]
socket = "~/mcp-sockets/fs.sock"
cmd = "npx"
args = ["-y", "@modelcontextprotocol/server-filesystem", "/home/user/docs"]
lazy_start = true
[servers.rmcp-memex]
socket = "~/.rmcp-servers/sockets/rmcp-memex.sock"
cmd = "/path/to/rmcp-memex"
args = ["serve", "--config", "config.toml", "--db-path", "~/.ai-memories/lancedb"]
env = { SLED_PATH = "~/.rmcp-servers/sled/memex" }
lazy_start = false
Parameter reference
| Parameter | Default | Description |
|---|---|---|
socket | required | Unix socket path (supports ~ expansion) |
cmd | required | MCP server command |
args | [] | Arguments for command |
env | {} | Environment variables for child process |
max_active_clients | 5 | Concurrent client limit |
lazy_start | false | Defer child spawn until first request |
max_request_bytes | 1048576 | Max request size (1 MiB) |
request_timeout_ms | 30000 | Request timeout (30s) |
restart_backoff_ms | 1000 | Initial restart delay (1s) |
restart_backoff_max_ms | 30000 | Max restart delay (30s) |
max_restarts | 5 | Restart limit (0 = unlimited) |
tray | false | Enable tray icon for this server |
status_file | none | Path for JSON status snapshots |
Client Configuration (Claude Desktop, etc.)
MCP hosts expecting STDIO communication connect through rmcp-mux-proxy:
{
"mcpServers": {
"rmcp-memex": {
"command": "rmcp-mux-proxy",
"args": ["--socket", "~/.rmcp-servers/sockets/rmcp-memex.sock"]
},
"loctree": {
"command": "rmcp-mux-proxy",
"args": ["--socket", "~/.rmcp-servers/sockets/loctree.sock"]
},
"brave-search": {
"command": "rmcp-mux-proxy",
"args": ["--socket", "~/.rmcp-servers/sockets/brave-search.sock"]
}
}
}
Each proxy instance translates STDIO <-> Unix socket, allowing standard MCP hosts to communicate with rmcp-mux managed servers.
CLI Reference
Main command
rmcp-mux --config mux.toml [OPTIONS]
Required:
--config <PATH>β Path to configuration file (TOML)
Server selection:
--only <NAMES>β Start only specified servers (comma-separated)--except <NAMES>β Start all servers except specified (comma-separated)
Runtime control:
--show-statusβ Show status of all servers and exit--restart-service <NAME>β Restart a specific server--tuiβ Launch interactive TUI dashboard
Examples:
# Start all servers from config
rmcp-mux --config mux.toml
# Start only memory and filesystem servers
rmcp-mux --config mux.toml --only memory,filesystem
# Start all except brave-search
rmcp-mux --config mux.toml --except brave-search
# Check status of running servers
rmcp-mux --config mux.toml --status
# Restart a specific server
rmcp-mux --config mux.toml --restart-service memory
# Interactive dashboard
rmcp-mux --config mux.toml --tui
Subcommands
daemon-status β Query running daemon
# Get status of running daemon (requires daemon to be running)
rmcp-mux daemon-status
# Output as JSON
rmcp-mux daemon-status --json
# Use custom status socket
rmcp-mux daemon-status --socket /custom/path.sock
Returns: version, uptime, server count, per-server status (active clients, pending requests, restarts, heartbeat latency).
health β Verify connectivity
# Check specific socket
rmcp-mux health --socket /tmp/mcp-memory.sock
# Check service from config
rmcp-mux health --config mux.toml --service memory
proxy β STDIO proxy
rmcp-mux proxy --socket /tmp/mcp-memory.sock
scan β Discover and generate configs
rmcp-mux scan \
--manifest ~/.codex/mcp-mux.toml \
--snippet ~/.codex/mcp-mux \
--socket-dir ~/.rmcp-servers/rmcp-mux/sockets
rewire β Update host configs
# Rewire a host config to use rmcp-mux proxy (creates .bak backup)
rmcp-mux rewire --host codex --socket-dir ~/.rmcp-servers/rmcp-mux/sockets
# Preview changes without writing
rmcp-mux rewire --host codex --dry-run
wizard β Interactive configuration
rmcp-mux wizard --config ~/.codex/mcp-mux.toml
Interactive TUI Dashboard
Launch with --tui for a real-time dashboard:
rmcp-mux --config mux.toml --tui
Display
- Server list with status indicators (running/stopped/error)
- Connected clients count per server
- Pending requests
- Restart count and last restart reason
- Real-time updates
Keyboard controls
| Key | Action |
|---|---|
j / Down | Move selection down |
k / Up | Move selection up |
r | Restart selected server |
s | Stop selected server |
S | Start selected server |
q / Esc | Quit |
Library Usage
Add to your Cargo.toml:
[dependencies]
rmcp-mux = { version = "0.3", default-features = false }
Basic Example - Single Mux Server
use rmcp_mux::{MuxConfig, run_mux_server};
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let config = MuxConfig::new("/tmp/my-mcp.sock", "npx")
.with_args(vec!["-y".into(), "@anthropic/mcp-server".into()])
.with_max_clients(10)
.with_service_name("my-mcp-server");
run_mux_server(config).await
}
Multiple Mux Instances (Single Process)
use rmcp_mux::{MuxConfig, spawn_mux_server, MuxHandle};
use std::time::Duration;
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let services = vec![
("memory", "/tmp/mcp-memory.sock", "npx", vec!["@mcp/server-memory"]),
("filesystem", "/tmp/mcp-fs.sock", "npx", vec!["@mcp/server-filesystem"]),
];
let mut handles: Vec<MuxHandle> = Vec::new();
for (name, socket, cmd, args) in services {
let config = MuxConfig::new(socket, cmd)
.with_args(args.into_iter().map(String::from).collect())
.with_service_name(name)
.with_request_timeout(Duration::from_secs(60));
handles.push(spawn_mux_server(config).await?);
}
for handle in handles {
handle.wait().await?;
}
Ok(())
}
Health Check
use rmcp_mux::check_health;
async fn verify_service() -> bool {
check_health("/tmp/mcp-memory.sock").await.is_ok()
}
Feature Flags
| Feature | Default | Description |
|---|---|---|
cli | yes | CLI binary, wizard, scan commands |
tray | yes | System tray icon support |
For library-only usage (minimal dependencies):
[dependencies]
rmcp-mux = { version = "0.3", default-features = false }
Runtime Behavior
Client handling
- New client connects to server's socket -> assigned
client_id - Messages get
global_id = c<client>:<seq> - Responses demuxed back to original client with local ID
- First
initializehits server; response cached - Later
initializecalls answered from cache
Safety guards
- Max request size β default 1 MiB
- Request timeout β default 30s with cleanup of pending calls
- Exponential restart backoff β 1s -> 30s with configurable limit
- Lazy start β defer child spawn until first request
Error handling
- Child exit or I/O failure -> restart child, clear cache/pending, send errors to affected clients
- Graceful shutdown (Ctrl+C) -> stop all children, delete all sockets
Project Structure
rmcp-mux/
βββ src/
β βββ lib.rs # Library entry point, MuxConfig, public API
β βββ config.rs # Config types, loading, validation
β βββ state.rs # MuxState, StatusSnapshot, helpers
β βββ scan.rs # Host discovery and rewiring (cli feature)
β βββ tray.rs # Tray icon (tray feature)
β βββ bin/
β β βββ rmcp_mux.rs # CLI binary (cli feature)
β β βββ rmcp_mux_proxy.rs # STDIO proxy (cli feature)
β βββ runtime/ # Core mux daemon
β β βββ mod.rs # run_mux, health_check
β β βββ types.rs # ServerEvent, constants
β β βββ client.rs # Client connection handling
β β βββ server.rs # Child process management
β β βββ proxy.rs # STDIO proxy logic
β β βββ status.rs # Status file writing & daemon status socket
β β βββ heartbeat.rs # Backend health monitoring
β βββ wizard/ # Interactive TUI wizard (cli feature)
βββ tools/
β βββ install.sh # One-liner installer
β βββ launchd/ # macOS launchd templates
βββ public/
βββ rmcp_mux_icon.png # Tray icon
Testing
# Run all tests
cargo test
# Run tests without tray feature (for CI/headless)
cargo test --no-default-features
# Linting
cargo clippy --all-targets --all-features
launchd (macOS)
Template at tools/launchd/rmcp-mux.sample.plist:
cp tools/launchd/rmcp-mux.sample.plist ~/Library/LaunchAgents/rmcp-mux.plist
# Edit paths: set --config to your mux.toml
launchctl load -w ~/Library/LaunchAgents/rmcp-mux.plist
Contributing
See .ai-agents/AI_GUIDELINES.md for development guidelines.
License
MIT
