Skip to content

Getting Started with MsgTier

MsgTier is a decentralized P2P messaging network that enables nodes to discover each other and communicate securely without a central server.

Installation

Install the latest release on Linux x64/arm64 or macOS arm64:

bash
curl -fsSL https://msgtier.oboard.fun/install.sh | bash

The default installation directory is ~/.local/bin. See Download for Windows, manual downloads, checksums and custom installation paths.

To build from source instead:

bash
git clone --recurse-submodules https://github.com/oboard/msgtier.git
cd msgtier
cd web/msgtier-web && pnpm install --frozen-lockfile && pnpm build
cd dist && zip -qr ../../dist.zip .
cd ../../..
moon update && moon install
moon build cmd/main --release --target native
# Executable: _build/native/release/build/cmd/main/main.exe

Configuration

Create a node.json configuration file for each node:

json
{
  "id": "1",
  "secret": "shared-secret-key",
  "listeners": [
    "udp://0.0.0.0:6666",
    "tcp://0.0.0.0:6667",
    "ws://0.0.0.0:6668"
  ],
  "peers": [
    "udp://127.0.0.1:6669",
    "ws://127.0.0.1:6670"
  ],
  "web_api": "127.0.0.1:9000",
  "scripts": {
    "open_browser": "open /Applications/Google\\ Chrome.app",
    "notify": "echo 'Message received'"
  }
}

Configuration Fields

FieldTypeDescription
idStringUnique identifier for this node
secretStringShared secret key (reserved for future use)
listenersArrayAddresses to listen on. Supported protocols: udp://, tcp://, ws://. Use 0.0.0.0 to bind all interfaces
peersArrayInitial peer addresses to connect to. Supported protocols: udp://, tcp://, ws://
relay_network_whitelistArray[String]List of allowed target networks for relay (default: ["*"])
relay_all_peer_rpcBooleanWhether to relay RPC messages even if not in whitelist (default: true)
foreign_relay_bps_limitNumberBandwidth limit (bytes/sec) for foreign network relay (default: 0 = unlimited)
web_apiStringHTTP server address (optional)
hot_reloadObjectRuntime hot reload policy. enable defaults to true. If secret is set, every hot update request must include it
scriptsObjectNamed scripts that can be triggered via messages
forwardsObjectBastion forward rules. Key is peer_id:rule_id, value is protocol://listen_host:listen_port
exposesObjectBastion expose rules. Key is rule id, value is protocol://target_host:target_port

Static fields:

  • id
  • secret
  • peers
  • listeners
  • web_api

Hot-reloadable fields:

  • scripts
  • forwards
  • exposes
  • other runtime options such as metadata, relay settings, upload_dir, and hot_reload

Bastion Port Forwarding

MsgTier can expose a static bastion tunnel between two peers. The simplest form uses shorthand strings so you only need to fill the peer and port:

Full guide: Port Forwarding

Forward side:

json
{
  "forwards": {
    "node-b:db": "tcp://127.0.0.1:15432"
  }
}

Expose side:

json
{
  "exposes": {
    "db": "tcp://127.0.0.1:5432"
  }
}

The forward side chooses the remote peer and the local listening port. The expose side only declares the local target. MsgTier matches the tunnel by peer_id:rule_id.

If you need UDP, the format is the same:

json
{
  "forwards": {
    "node-b:dns": "udp://127.0.0.1:1053"
  },
  "exposes": {
    "dns": "udp://127.0.0.1:53"
  }
}

Running Nodes

Single Node

bash
./msgtier node.json

Output:

bash
X25519 key pair generated successfully
{
  "id": "1",
  "secret": "secret-key",
  "listeners": ["0.0.0.0:6666"],
  "peers": [],
  "web_api": "127.0.0.1:9000"
}
Listening on 0.0.0.0:6666
HTTP API listening on http://127.0.0.1:9000

Multi-Node Network

Terminal 1 - Node 1:

bash
./msgtier node1.json

Terminal 2 - Node 2:

bash
./msgtier node2.json

Terminal 3 - Node 3:

bash
./msgtier node3.json

End-to-End Encryption

MsgTier automatically handles encryption using X25519 ECDH:

  1. On startup: Each node generates an X25519 key pair (fast elliptic curve)
  2. During handshake: Public keys are exchanged in hello/welcome messages
  3. Shared secret: Both peers compute the same shared secret via ECDH
  4. When sending: Messages are symmetrically encrypted with the shared secret
  5. When receiving: Messages are decrypted with the same shared secret

You'll see log messages like:

bash
X25519 key pair generated successfully
Computed shared secret with peer 2

If a peer's shared secret is not available, messages are sent unencrypted with a warning:

bash
Warning: Sending unencrypted message to peer_id (no shared secret available)

Sending Messages

HTTP API

Send a message to a peer using the REST API:

bash
curl -X POST 'http://127.0.0.1:9000/api/send' \
  -H 'target: 1' \
  -d 'script_name'
  • target header: ID of the destination peer
  • Body: Name of the script to trigger

Script Execution

When a message is received, if the message body matches a script name in the config, the script is executed:

json
"scripts": {
  "chrome": "open /Applications/Google\\ Chrome.app"
}

Send via HTTP:

bash
curl -X POST 'http://localhost:9000/api/send' \
  -H 'target: 1' \
  -d 'chrome'

Node will execute: open /Applications/Google\ Chrome.app

Checking Connection Status

View connection status and peer information:

bash
curl http://127.0.0.1:9000/api/status

Troubleshooting

Connection Issues

Problem: Nodes aren't discovering each other

Solution:

  • Ensure firewall allows UDP on configured ports
  • Verify peer addresses are correct and reachable
  • Check logs for "Discovered new peer" messages

Script Not Executing

Problem: Message received but script didn't run

Solution:

  • Verify script name exactly matches config
  • Check script syntax (platform-specific shells)
  • View logs for script execution status

Encryption Issues

Problem: "No public key available" warnings

Solution:

  • Wait for peers to complete handshake (hello/welcome exchange)
  • Check that peers are running compatible versions
  • Verify network connectivity

High Latency

Problem: Messages taking long time to deliver

Solution:

  • Check connection status: curl http://localhost:9000/api/status
  • Verify heartbeat/pong responses working
  • Consider network topology - use nodes as relays

Next Steps

  • Check API Examples for detailed endpoint documentation
  • Explore cross-platform script capabilities
  • Set up multi-node clusters for testing message relay