The Intermud3 Gateway provides a JSON-RPC 2.0 API that allows MUD servers to integrate with the global Intermud-3 network. The API supports both WebSocket and TCP connections, enabling real-time bidirectional communication between MUDs and the I3 network.
Current Status: Phase 3 Complete (2025-08-20) - Full implementation with 78% test coverage, 1200+ tests, achieving 1000+ msg/sec throughput with <100ms latency.
- Connection and Authentication
- Transport Protocols
- Message Format
- Error Handling
- API Methods
- Events and Notifications
- Rate Limiting
- Session Management
Connect to the WebSocket endpoint:
ws://localhost:8080/ws
Connect to the TCP socket:
localhost:8081
All connections require authentication using an API key. Authentication can be done in two ways:
X-API-Key: your-api-key-here{
"jsonrpc": "2.0",
"id": 1,
"method": "authenticate",
"params": {
"api_key": "your-api-key-here"
}
}Response:
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"status": "authenticated",
"mud_name": "YourMUD",
"session_id": "unique-session-id"
}
}- URL:
ws://host:port/ws - Protocol: JSON-RPC 2.0 over WebSocket frames
- Benefits: Real-time bidirectional communication, automatic reconnection support
- Message Format: JSON objects sent as WebSocket text frames
- Host/Port: Configured in gateway settings (default: port 8081)
- Protocol: Line-delimited JSON-RPC 2.0
- Message Format: JSON objects terminated by newline (
\n) - Benefits: Compatibility with older systems, simple implementation
All messages follow the JSON-RPC 2.0 specification:
{
"jsonrpc": "2.0",
"id": "unique-request-id",
"method": "method_name",
"params": {
"parameter1": "value1",
"parameter2": "value2"
}
}{
"jsonrpc": "2.0",
"id": "unique-request-id",
"result": {
"status": "success",
"data": "response_data"
}
}{
"jsonrpc": "2.0",
"method": "event_name",
"params": {
"event_data": "value"
}
}| Code | Name | Description |
|---|---|---|
| -32700 | Parse Error | Invalid JSON received |
| -32600 | Invalid Request | JSON is not a valid request object |
| -32601 | Method Not Found | Method does not exist |
| -32602 | Invalid Params | Invalid method parameters |
| -32603 | Internal Error | Internal JSON-RPC error |
| Code | Name | Description |
|---|---|---|
| -32000 | Not Authenticated | Client not authenticated |
| -32001 | Rate Limit Exceeded | Rate limit exceeded |
| -32002 | Permission Denied | Permission denied for method |
| -32003 | Session Expired | Session has expired |
| -32004 | Gateway Error | Gateway communication error |
{
"jsonrpc": "2.0",
"id": "request-id",
"error": {
"code": -32602,
"message": "Invalid params",
"data": {
"field": "target_mud",
"reason": "MUD not found in network"
}
}
}Send a direct message to a user on another MUD.
Parameters:
target_mud(string, required): Name of the target MUDtarget_user(string, required): Name of the target usermessage(string, required): Message to send (max 2048 characters)from_user(string, optional): Sender's username
Example:
{
"jsonrpc": "2.0",
"id": 1,
"method": "tell",
"params": {
"target_mud": "OtherMUD",
"target_user": "PlayerName",
"message": "Hello from our MUD!",
"from_user": "MyPlayer"
}
}Response:
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"status": "success",
"message": "Tell sent successfully"
}
}Send an emote to a specific user.
Parameters:
target_mud(string, required): Name of the target MUDtarget_user(string, required): Name of the target useremote(string, required): Emote text (max 1024 characters)from_user(string, optional): Sender's username
Example:
{
"jsonrpc": "2.0",
"id": 2,
"method": "emoteto",
"params": {
"target_mud": "OtherMUD",
"target_user": "PlayerName",
"emote": "waves enthusiastically",
"from_user": "MyPlayer"
}
}Send a message to a channel.
Parameters:
channel(string, required): Channel namemessage(string, required): Message to send (max 2048 characters)from_user(string, optional): Sender's usernamevisname(string, optional): Visible name for sender
Example:
{
"jsonrpc": "2.0",
"id": 3,
"method": "channel_send",
"params": {
"channel": "intermud",
"message": "Hello everyone!",
"from_user": "MyPlayer"
}
}Send an emote to a channel.
Parameters:
channel(string, required): Channel nameemote(string, required): Emote text (max 1024 characters)from_user(string, optional): Sender's usernamevisname(string, optional): Visible name for sender
List users on a MUD.
Parameters:
target_mud(string, required): Name of the target MUDfilters(object, optional): Filtering optionsmin_level(number): Minimum user levelmax_level(number): Maximum user levelrace(string): Filter by raceguild(string): Filter by guild
Example:
{
"jsonrpc": "2.0",
"id": 4,
"method": "who",
"params": {
"target_mud": "OtherMUD",
"filters": {
"min_level": 10,
"race": "human"
}
}
}Response:
{
"jsonrpc": "2.0",
"id": 4,
"result": {
"status": "success",
"mud_name": "OtherMUD",
"users": [
{
"name": "Player1",
"level": 15,
"race": "human",
"guild": "warriors",
"idle_time": 120
}
],
"count": 1
}
}Get detailed information about a user.
Parameters:
target_mud(string, required): Name of the target MUDtarget_user(string, required): Name of the target user
Example:
{
"jsonrpc": "2.0",
"id": 5,
"method": "finger",
"params": {
"target_mud": "OtherMUD",
"target_user": "PlayerName"
}
}Find a user on the network.
Parameters:
target_user(string, required): Name of the user to locate
Example:
{
"jsonrpc": "2.0",
"id": 6,
"method": "locate",
"params": {
"target_user": "PlayerName"
}
}Response:
{
"jsonrpc": "2.0",
"id": 6,
"result": {
"status": "success",
"user_name": "PlayerName",
"locations": [
{
"mud_name": "MUD1",
"status": "online",
"idle_time": 300
}
],
"found": true,
"count": 1
}
}Get list of MUDs on the network.
Parameters:
refresh(boolean, optional): Force refresh from router (default: false)filter(object, optional): Filtering optionsstatus(string): Filter by status ("up" or "down")driver(string): Filter by driver typehas_service(string): Filter by service availability
Example:
{
"jsonrpc": "2.0",
"id": 7,
"method": "mudlist",
"params": {
"refresh": false,
"filter": {
"status": "up",
"has_service": "tell"
}
}
}Join a channel.
Parameters:
channel(string, required): Channel name (max 32 characters)listen_only(boolean, optional): Join in listen-only mode (default: false)user_name(string, optional): Username for channel (default: "System")
Example:
{
"jsonrpc": "2.0",
"id": 8,
"method": "channel_join",
"params": {
"channel": "intermud",
"listen_only": false,
"user_name": "MyPlayer"
}
}Leave a channel.
Parameters:
channel(string, required): Channel nameuser_name(string, optional): Username for channel
List available channels.
Parameters:
refresh(boolean, optional): Force refresh from routerfilter(object, optional): Filtering optionstype(number): Channel type (0=public, 1=private)owner(string): Filter by ownermin_members(number): Minimum member count
Response:
{
"jsonrpc": "2.0",
"id": 9,
"result": {
"status": "success",
"channels": [
{
"name": "intermud",
"type": 0,
"owner": "",
"subscribed": true,
"member_count": 25
}
],
"count": 1,
"subscribed_channels": ["intermud"]
}
}List members of a channel.
Parameters:
channel(string, required): Channel name
Get channel message history.
Parameters:
channel(string, required): Channel namelimit(number, optional): Number of messages (1-100, default: 50)before(string, optional): Get messages before timestampafter(string, optional): Get messages after timestamp
Health check and heartbeat.
Example:
{
"jsonrpc": "2.0",
"id": 10,
"method": "ping"
}Response:
{
"jsonrpc": "2.0",
"id": 10,
"result": {
"pong": true,
"timestamp": 1642678800.123
}
}Get gateway status and session information.
Response:
{
"jsonrpc": "2.0",
"id": 11,
"result": {
"connected": true,
"mud_name": "YourMUD",
"session_id": "unique-session-id",
"uptime": 3600.5
}
}The gateway sends events as JSON-RPC notifications (no response expected).
Received when a tell arrives for a user.
{
"jsonrpc": "2.0",
"method": "tell_received",
"params": {
"from_mud": "RemoteMUD",
"from_user": "SenderName",
"to_user": "RecipientName",
"message": "Hello there!",
"timestamp": "2025-01-20T10:30:00Z"
}
}Received when an emote is sent to a user.
{
"jsonrpc": "2.0",
"method": "emoteto_received",
"params": {
"from_mud": "RemoteMUD",
"from_user": "SenderName",
"to_user": "RecipientName",
"emote": "waves at you",
"timestamp": "2025-01-20T10:30:00Z"
}
}Received when a message is sent to a subscribed channel.
{
"jsonrpc": "2.0",
"method": "channel_message",
"params": {
"channel": "intermud",
"from_mud": "RemoteMUD",
"from_user": "SenderName",
"message": "Hello channel!",
"visname": "SenderName",
"timestamp": "2025-01-20T10:30:00Z"
}
}Received when an emote is sent to a subscribed channel.
Notifies when a MUD comes online.
{
"jsonrpc": "2.0",
"method": "mud_online",
"params": {
"mud_name": "NewMUD",
"info": {
"driver": "FluffOS",
"mud_type": "LP",
"services": ["tell", "channel", "who"],
"admin_email": "admin@newmud.com"
}
}
}Notifies when a MUD goes offline.
Notifies when successfully joined a channel.
Notifies when left a channel.
Notifies of system errors.
Notifies when gateway reconnects to router.
- Per session: 100 requests per minute
- Burst allowance: 20 requests
- By method: Specific limits per method type
tell: 30 per minutechannel_send: 50 per minutewho: 10 per minutemudlist: 5 per minute
Rate limit information is included in error responses:
{
"jsonrpc": "2.0",
"id": 1,
"error": {
"code": -32001,
"message": "Rate limit exceeded",
"data": {
"retry_after": 60,
"limit": 100,
"remaining": 0
}
}
}- Connection: Client connects via WebSocket or TCP
- Authentication: Client provides API key
- Session Creation: Server creates session with unique ID
- Activity Tracking: Server tracks all client activity
- Timeout: Session expires after inactivity (default: 1 hour)
- Cleanup: Server cleans up expired sessions
- Sessions persist across reconnections using session ID
- Message queue maintains offline messages (max 1000, TTL 5 minutes)
- Channel subscriptions are restored on reconnection
Each session tracks:
- Messages sent/received
- Method call counts
- Error counts
- Connection duration
- Last activity timestamp
api:
host: "0.0.0.0"
port: 8080
websocket:
enabled: true
max_connections: 1000
ping_interval: 30
tcp:
enabled: true
port: 8081
max_connections: 500
auth:
enabled: true
api_keys:
- key: "your-api-key"
mud_name: "YourMUD"
permissions: ["tell", "channel", "info"]api:
rate_limits:
default:
per_minute: 100
burst: 20
by_method:
tell: 30
channel_send: 50GET /health
Response:
{
"status": "healthy",
"service": "i3-gateway-api",
"websocket_connections": 42,
"active_sessions": 38
}GET /health/live
GET /health/ready
GET /metrics
Returns Prometheus-format metrics.
- Use WebSocket for real-time applications
- Implement reconnection logic with exponential backoff
- Handle session restoration gracefully
- Monitor connection health with ping/pong
- Always check for error responses
- Implement retry logic for transient errors
- Log all errors for debugging
- Handle rate limiting gracefully
- Batch related operations when possible
- Use appropriate rate limits
- Monitor session metrics
- Implement message queuing for offline handling
- Keep API keys secure
- Use TLS in production
- Implement proper input validation
- Monitor for abuse patterns
import asyncio
import websockets
import json
async def send_tell():
uri = "ws://localhost:8080/ws"
async with websockets.connect(uri) as websocket:
# Authenticate
auth_msg = {
"jsonrpc": "2.0",
"id": 1,
"method": "authenticate",
"params": {"api_key": "your-api-key"}
}
await websocket.send(json.dumps(auth_msg))
response = await websocket.recv()
print("Auth response:", response)
# Send tell
tell_msg = {
"jsonrpc": "2.0",
"id": 2,
"method": "tell",
"params": {
"target_mud": "OtherMUD",
"target_user": "Player",
"message": "Hello!",
"from_user": "MyPlayer"
}
}
await websocket.send(json.dumps(tell_msg))
response = await websocket.recv()
print("Tell response:", response)
asyncio.run(send_tell())async def handle_events():
uri = "ws://localhost:8080/ws"
async with websockets.connect(uri) as websocket:
# Authenticate first...
# Listen for events
async for message in websocket:
data = json.loads(message)
if data.get("method") == "tell_received":
params = data["params"]
print(f"Tell from {params['from_user']}@{params['from_mud']}: {params['message']}")
elif data.get("method") == "channel_message":
params = data["params"]
print(f"[{params['channel']}] {params['from_user']}: {params['message']}")This API reference provides a complete guide to integrating with the Intermud3 Gateway. For additional examples and integration guides, see the accompanying documentation files.