DEV Community

Daniel
Daniel

Posted on Fully Autonomous

Your First MatrixSwarm: Five Agents, One Railgun, and a Server That Finally Texts Back

You have a Linux server. You can SSH into it. You can stare at its logs until the letters begin to rearrange themselves into career advice.

What you would prefer is a small, understandable setup: send commands from Phoenix, see the agents and their logs, and get a Telegram message when someone successfully logs in over SSH.

A reasonable request. Naturally, we have brought a Railgun.

This walkthrough builds that setup from the beginning: install MatrixOS, create a Phoenix Swarm Workspace, assign its connections, deploy it through Railgun, and verify the complete path with a controlled login.

The five agents we add are matrix_https, matrix_websocket, log_streamer, telegram_relay, and gatekeeper. Phoenix creates the matrix root for us, so the finished tree contains six nodes.

A naming note before anyone searches the palette for twenty minutes: the HTTP command-ingress agent is named matrix_https in the current catalog, and the Telegram agent is telegram_relay. Those are the names used below.

The mission map

Component Responsibility
Phoenix The operator application: vault, Registry, workspace editor, and live cockpit
MatrixOS The runtime installed on the Linux target
Railgun Installs the runtime and launches deployments through SSH
matrix Starts the swarm, establishes its chain of trust, and routes commands
matrix_https Receives authenticated Phoenix commands over HTTPS
matrix_websocket Provides the live return connection for replies, alerts, and session traffic
log_streamer Supplies agent runtime logs to Phoenix
gatekeeper Watches authentication-log entries for successful SSH logins
telegram_relay Sends alert messages to the configured Telegram chat

Here is the traffic flow. These arrows describe communication, not the parent-child layout of the workspace:

INSTALL / LAUNCH
Phoenix → Railgun → SSH → MatrixOS / MatrixD

LIVE CONTROL
Phoenix → HTTPS ingress → Matrix → requested agent
Agent reply / logs → WebSocket relay → Phoenix

LOGIN NOTIFICATION
SSH authentication log → Gatekeeper → hive.alert → Telegram relay → your chat
                                          └──→ WebSocket relay → Phoenix feed
Enter fullscreen mode Exit fullscreen mode

SSH is the installation and launch route. HTTPS and WebSocket are the live cockpit routes. Successfully connecting by SSH does not prove the cockpit ports are reachable.

Telegram is an alert destination here. Typing “restart everything” into the bot chat is not part of this agent’s command interface, which is probably good news for everyone in the group.

1. Prepare the target and open your vault

Use a Linux machine you administer, preferably a lab VM for the first run. The current installer supports provisioning through apt-get or dnf. It provisions the Python 3.12 runtime it needs, including a verified source-build fallback when the required runtime is unavailable from the host’s packages.

Have these ready:

  • Phoenix with an unlocked encrypted vault;
  • an SSH account on the target, with root access or the passwordless-sudo access required by Railgun’s provisioning steps;
  • the target’s independently verified SSH host-key fingerprint;
  • an address Phoenix can reach, two available non-privileged TCP ports, and matching network/firewall access;
  • a Telegram bot token and destination chat ID;
  • a real authentication log that records SSH events.

The runtime service account is a separate matter from the privileged SSH account. Railgun uses provisioning privileges to prepare the host, then runs the swarm under its dedicated non-root Linux user.

For the examples, we will use:

Example item Value
Target reachable address 10.20.30.40
Phoenix workstation’s source address 10.20.30.10
HTTPS command port 8443
WebSocket return port 8765
Universe first-swarm
Swarm Linux user matrix-first-swarm

These are example values, not a server waiting for you. Replace them with your network’s actual values. If NAT or a VPN changes the source address seen by the target, use that observed source when configuring allowlists.

Permit the two cockpit ports from the operator’s intended address or network, and keep SSH access available for installation. The target also needs outbound access for installation dependencies and Telegram delivery. A new universe on the same server needs available ports too; a different name does not let two processes own the same socket.

2. Put SSH in the Registry

Open Registry, create an SSH record, and give it a recognizable label, such as lab-server-ssh.

In its Connection tab, enter Host, Port, Username, and Trusted Fingerprint. In Authentication & Keys, select the authentication method you actually use and enter the corresponding existing credentials. An encrypted private key needs its own passphrase; that is different from the server account’s password.

Use Test Connection, then Save to Vault. Establish the host fingerprint from a trusted source, such as the server console or your provisioning inventory. Treat a fingerprint mismatch as something to investigate rather than a speed bump to flatten.

The SSH record tells Railgun which machine it may contact. It does not configure the HTTPS or WebSocket agents. Those get their own records shortly.

Credentials belong in the vault. A screenshot of a private key is a surprisingly efficient way to turn documentation into an incident.

3. Install MatrixOS with Railgun

Open Railgun → Check Remote Host…, select the SSH target, and run Run Full Check. Review the results for SSH access, OS, Python, disk space, system clock, /matrix, and an existing installation. This is a useful preflight, not a guarantee that every application-level requirement has been satisfied.

If MatrixOS is already installed and current enough for this Phoenix build, proceed to the workspace steps. Otherwise open Railgun → Install MatrixOS….

Choose the source

Install Mode What it uses
Install from GitHub The project’s GitHub repository, fetched by the remote installer
Local Full Install Your selected local MatrixOS source folder, uploaded to the target

For Local Full Install, Local Source Path should point to the MatrixOS root, the directory containing its runtime source such as agents, core, and scripts. In the monorepo, this is the matrixos directory—not the Phoenix application directory or a Python virtual environment.

Use matching Phoenix and MatrixOS versions. A local UI describing features that an older remote runtime has never met is not a compatibility strategy.

Choose the environment and target

For a fresh installation, select Create new venv. Skip Python setup is for an already suitable MatrixOS environment; it is not the beginner’s “make this faster” button.

Select the saved SSH target under Deploy To, then click Install MatrixOS.

The installer places MatrixOS under /matrix, creates or uses its isolated environment at /matrix/.venv, installs dependencies, and prepares the matrixd launcher. Watch the output and wait for Installation complete. An upload reaching 100% is only an upload milestone; dependency installation and validation can still be running.

If Python must be built, allow that stage to finish. The progress window has not entered a reflective phase. Compilers simply have hobbies.

Installing MatrixOS prepares the runtime. It does not deploy this swarm yet.

4. Create the three application connection records

In Registry, create an HTTPS record, a WSS record, and a Telegram record. You can also create or select these from the workspace’s requirement-assignment controls; preparing them now makes the later steps easy to follow.

HTTPS: Phoenix sends commands

For the HTTPS record:

Field Example
Label first-swarm-https
Host 10.20.30.40, without a URL scheme or path
Port 8443
Allowlist IPs The operator source IP actually seen by the target
Channel outgoing.command
Primary Outgoing Transport Enabled for this single-command-transport example
Directive Path Keep config

Use an address Phoenix can reach. 0.0.0.0 is not a destination to enter here. The current agents listen on the target’s interfaces; the Registry Host supplies the address used to connect to them.

WSS: Phoenix receives live results

For the WSS record, use the same reachable host and port 8765. Set the appropriate source-IP allowlist, keep the channel payload.reception, enable Primary Payload Reception Transport, and keep Directive Path config.

Those channel names are from Phoenix’s perspective: commands go out, payloads come back. The WebSocket agent’s “egress” role describes traffic leaving the swarm toward Phoenix.

Leave the generated Serial values alone. Labels are for humans; identities and references are doing additional work behind the curtain.

Telegram: give the messenger an address

For a first exercise, a new dedicated bot and a private test chat are straightforward:

  1. Contact Telegram’s official BotFather, send /newbot, and follow its prompts to obtain the bot token.
  2. Open a private conversation with your new bot and send /start or a message. A bot needs that initial user contact before ordinary private messages can be sent back.
  3. Obtain that conversation’s numeric chat ID, then save the token and chat ID in the Telegram Registry record.

Telegram documents bot creation in its official tutorial. For a new bot with no webhook or other update consumer, you can retrieve an incoming update through getUpdates and read message.chat.id from your test message. Use a local API client and supply the token privately; do not put a real token into a tutorial, a shared screenshot, or a browser address you plan to share. If a webhook is already configured, getUpdates is unavailable—use the existing integration’s received update instead.

The Registry fields are Label, Chat ID, and Bot Token. Keep the Telegram channel selection and Directive Path config/telegram. The token is the bot credential; the chat ID is the destination. They are not interchangeable, despite both looking like something a database coughed up.

For a group destination, add the bot to that group, use the group’s actual chat ID, and ensure the bot can send there. Verify the destination before connecting real login notifications to it.

5. Build the workspace tree

Click Deploy in Phoenix’s main toolbar. This opens Swarm Workspaces. Choose New for this tutorial, or Open an existing workspace you intend to extend. The manager also offers Clone when you want a separate editable copy.

A new workspace starts with the matrix root. In the Agent picker, search for each of the five agents and drag it onto empty canvas space or directly onto Matrix. For this example, all five should be direct children of the root:

matrix
├── matrix_https
├── matrix_websocket
├── log_streamer
├── telegram_relay
└── gatekeeper
Enter fullscreen mode Exit fullscreen mode

Drop onto another agent and you can create a different parent relationship. If that happens unintentionally, right-click the misplaced node and use Reparent To → matrix.

This is the agent hierarchy. You do not need to put Telegram underneath Gatekeeper to route its alerts. The service roles supply that connection.

Select a node to inspect it on the left. Double-click a configurable agent to open its configuration editor. If the picker appears to have lost an agent, use Clear filters before filing a missing-person report.

The workspace saves changes to the vault. Watch for Saved to Vault ✓; a save failure has a Retry Save action. Do not close an editor that is still telling you its changes have not been saved. You can rename the workspace in the manager to something recognizable, such as First Swarm Lab.

6. Satisfy the requirements without collecting loose certificates

Select each node and look at Agent Inspector → Requirements.

Node What you should see or assign
matrix Automatic packet-signing material
matrix_https Automatic signing and connection certificates; assign the HTTPS Registry record
matrix_websocket Automatic signing and connection certificates; assign the WSS record
log_streamer Automatic packet-signing material
telegram_relay Automatic packet-signing material; assign the Telegram record
gatekeeper No manual Registry requirement in the current palette entry; configure its behavior separately

AUTOGEN rows are generated during compilation. They are not missing credentials that you must hunt down on the filesystem. For assignable rows, use Assign or change, select the correct Registry record, and confirm that the row is satisfied.

Leave the supplied signing and certificate requirements intact. The deployment compiles the corresponding agent and Phoenix-side material, including the connection certificates used for mutual TLS. A normal browser visiting the port is not the intended client and may be rejected because it lacks that client identity.

Missing required assignments stop deployment. This is helpful. Discovering an absent Telegram token before launch is considerably less dramatic than discovering it during an incident.

7. Configure the agents and keep their service roles

For this first swarm, most defaults are useful. The important settings are the ones that let the agents find each other and do their actual jobs.

HTTPS and WebSocket

Double-click each transport agent and leave Enable Lockdown (Disable Packet Processing) unchecked for this exercise. Host, port, and allowlist settings come from the Registry records assigned above.

Keep the WebSocket relay’s supplied roles, including hive.rpc and hive.alert. These let it carry replies and receive alerts. Removing roles to make the configuration look tidier is how a perfectly healthy connection becomes a remarkably quiet one.

Log streamer

Keep log_streamer and its hive.log_streamer service role. Phoenix requests an agent’s runtime log through this service when you select that agent in the live tree.

It supplies visibility into the swarm. Gatekeeper itself reads the operating system’s SSH authentication log; log_streamer does not take over that job.

Telegram relay

Open telegram_relay and keep Enable Telegram alert delivery enabled. Leave Encrypt Telegram alert message off for the initial delivery test; we will cover that option below.

Keep its hive.alert role. Gatekeeper sends to that role, and the relay publishes the message to the chat configured in its Registry record. WebSocket also advertises the alert role, so a connected Phoenix session can receive the event too.

No hand-written destination UUID is needed for this basic arrangement.

Gatekeeper

Start with these settings:

Setting First-run choice
Alert Role hive.alert
Ignore IPs Empty while testing
Log Path The target’s real SSH authentication log; read the path-selection note below
MaxMind DB An existing GeoLite2 City database, if you want location enrichment

Gatekeeper follows new log lines with tail -n 0 -F. It recognizes successful OpenSSH-style entries containing Accepted and from, extracts the login account and source address, and sends an alert. It does not replay yesterday’s log when it starts.

The name sounds like a bouncer. In this setup, its job is to notice who came through the door and call the operator. It does not authenticate SSH users, block a login, ban addresses, or turn a successful login into proof of compromise.

Path selection matters: the current implementation prefers /var/log/secure when that file exists, then /var/log/auth.log, and only then the configured fallback. Confirm the path reported in its startup log. On a host that only keeps authentication events in the journal, configure the system logger to produce a suitable text log; creating an empty file does not persuade SSH to write into it.

Railgun derives log-access needs from the swarm and provisions the runtime account accordingly. Check its permission output. Initial access to an existing file is only part of the job: the account must still be able to read new files after log rotation. The current provisioning includes a persistent rule for the supported secure/rsyslog path; auth.log rotation may need distro-specific log-creation or ACL configuration. Verify that on your host rather than making authentication logs world-readable.

Optional MaxMind data adds a location estimate. Missing location data does not make a successful login disappear. An IP-derived city is context, not a sworn witness.

A current-build detail: the editor exposes Enable GeoIP and Always Alert, but the successful-login path does not currently use those switches to gate its lookup or apply the cooldown helper. Do not rely on those switches to suppress lookups or throttle this flow. Ignore IPs is an exact-address exclusion list; leave it empty until the test works, and add only intentional exclusions afterward.

Gatekeeper also contacts api.ipify.org to obtain the server’s public IP while constructing alerts. That outbound dependency can delay processing if it stalls. This walkthrough promises a verifiable notification path, not a fictional millisecond delivery guarantee.

8. Deploy the workspace through Railgun

Your workspace is the editable recipe in the vault. A deployment compiles that recipe, resolves its Registry references, generates the necessary identities, and launches an instance on the target.

Click Deploy inside the workspace. Resolve any missing requirements before proceeding.

Give the deployment a recognizable Deployment Label, then review Directive Deployment Options:

Option Choice for this first deployment
SSH Target The tested SSH Registry record
Universe Name first-swarm, or another unused simple name
Swarm Linux User A dedicated non-root account, such as matrix-first-swarm
Embed agent sources (Clown Car) Leave off when using the matching installed MatrixOS runtime
View the fully resolved directive after dependency to agent mappings Keep enabled so you can review the result
--protect-memory Keep enabled
--debug, --rug-pull, --clean Leave off for this tutorial

The label is for your eyes. The universe is an operational identifier: use a simple value without spaces, and check it explicitly rather than accepting a long display label copied into the field.

Review --reboot: it is enabled by default in the current dialog. Deploying to an existing universe is an operational change, not a harmless preview. Use a new universe and free ports for this exercise. Do not select every flag because they look lonely.

The optional Clown Car mode embeds agent source into the deployment. It does not replace installing MatrixOS, Python, or dependencies. For the beginner path here, the installed runtime supplies the agents.

There is also an option to remove previous deployment records after success for the same universe and target IP. That controls saved deployment records; it is not permission to clean arbitrary files on the server. Review it if you want to retain older records.

Read the staging view, then launch

With the preview option selected, Phoenix opens Directive Encryption Staging. Check the agent tree, target addresses, ports, alert role, and resolved assignments.

The resolved view can contain secrets. Review it locally; do not paste the entire thing into a support thread. “Please find attached our credentials” is not a diagnostic format.

Encrypt & Save commits this deployment and continues into the Railgun launch flow. It is the launch action for this workflow, not a button for saving an unfinished workspace.

What Railgun does

Railgun checks the pinned SSH target and the remote MatrixD launch capability, prepares the dedicated runtime user and agent-specific host access, and sends a sealed boot envelope over SSH standard input. MatrixD receives and processes that envelope to start the selected universe.

The sealed launch path avoids staging the plaintext directive and key as ordinary launch files or putting them in command-line arguments. That does not make the entire server diskless: the installed runtime, logs, and normal agent state still exist. Memory protection also does not make the process inaccessible to root.

Watch the Railgun output for completion and a successful exit. A saved deployment record alone is insufficient evidence—the record can exist before remote launch is confirmed.

If the SSH session times out or you cancel the local operation, inspect the target and the Swarms view before launching again. Stopping the local wait does not prove that the remote process stopped. Distributed systems remain committed to making “did it happen?” a full-time occupation.

9. Connect Phoenix and prove the whole route

Use Connect and select the deployment you just launched. Phoenix uses that deployment’s transport records and generated credentials for the HTTPS/WSS session.

Work through these checks in order:

  1. Live tree: confirm that the root and five child agents appear and report current activity.
  2. Agent logs: select Gatekeeper in the live tree and inspect Agent Logs. The selection requests the log stream. Look for its actual authentication-log path and any read errors.
  3. Relay health: select the Telegram relay and check that delivery is enabled and there are no missing-configuration or API errors.
  4. Fresh login: keep your existing administrative session open and make one new, authorized SSH login from an address absent from Gatekeeper’s ignore list. Do this after Gatekeeper has started following the log.
  5. Source event: confirm that the target recorded the corresponding successful OpenSSH authentication entry.
  6. Delivery: look for the event in the Phoenix alert feed and the intended Telegram chat. The relay’s successful-send log is useful supporting evidence; check the actual destination too.

The notification should identify the login account, source IP, authentication method, and recorded time, with location information when available. Some fields, such as terminal details, may be unknown. That is a better answer than confident fiction wearing a dashboard badge.

Do not test this by attacking your own password prompt. This tutorial exercises the successful-login flow. An ordinary authorized login is sufficient.

Once the message arrives, you have demonstrated the complete chain:

real SSH login
  → real authentication entry
  → Gatekeeper
  → hive.alert
  → Telegram relay
  → the right chat
Enter fullscreen mode Exit fullscreen mode

You also have a separate way to observe the agents through Phoenix and log_streamer. That makes the next failure diagnosable instead of merely atmospheric.

10. Optional: encrypt the Telegram alert body

After ordinary delivery works, enable Encrypt Telegram alert message in the relay’s configuration and deploy the updated workspace. Workspace edits affect the next deployment; saving the recipe does not silently rewrite a running swarm.

With encryption enabled, the relay signs and encrypts the alert body using the deployment’s assigned packet keys. Telegram receives a wrapped message beginning with:

MATRIXSWARM-ENCRYPTED-ALERT-V1
Enter fullscreen mode Exit fullscreen mode

It will look less like a login notification and more like a keyboard falling down a staircase. That is expected.

In Phoenix, open the Telegram relay’s panel, paste the complete wrapped alert, and use Decrypt with the matching deployment credentials. Phoenix verifies and displays the recovered message. Retain the appropriate deployment material if you need to read alerts from older deployments.

If the relay cannot create the encrypted wrapper, it blocks that send rather than falling back to plaintext. Check its logs when testing.

This option protects the alert body. Telegram still handles the bot/chat relationship and delivery metadata. The wrapper’s expiry information is not a Telegram self-destruct timer; Phoenix can mark an expired message as view-only, and the chat message is not automatically deleted by that setting.

11. When the server declines to text back

Symptom Check first
MatrixOS installation failed Actual installer output, supported package manager, provisioning privileges, network access, and disk space
Workspace refuses deployment Unassigned Registry requirements and invalid deployment fields
SSH works, Phoenix does not connect Reachable Registry Host, both cockpit ports, firewall rules, actual source-IP allowlists, correct deployment credentials, and transport lockdown settings
Agents appear, logs do not log_streamer, its hive.log_streamer role, and the WebSocket return path
Gatekeeper is alive but quiet Its selected log path, runtime-account read access, a fresh Accepted entry, and exact IP exclusions
Alerts stop after log rotation Permissions on newly created authentication logs and persistent logging/rotation configuration
Gatekeeper processing stalls Authentication-log following, optional lookup errors, and outbound access to api.ipify.org
Telegram has nothing Bot token, correct chat ID, initial user contact, send permissions, delivery enabled, shared hive.alert role, and outbound Telegram API access
Encrypted Telegram text will not open Complete wrapper, matching deployment keys, verification status, and relay encryption logs

Check one hop at a time. Reinstalling everything because a chat ID is wrong is technically activity, but so is running in circles with a clipboard.

The workflow you can reuse

The pattern for the next swarm is the same:

Install the runtime once → create or clone a workspace → add agents → assign Registry requirements → configure behavior → deploy → connect → test a real event.

Keep the small transport-and-logging foundation when you want a live Phoenix cockpit. Add the next useful worker beneath Matrix, configure its service roles and requirements, and verify its output. Telegram can carry other agents’ compatible alerts too; Gatekeeper is simply the first producer in this exercise.

You now have a swarm you can command, observe, and hear from when someone successfully logs in. Six nodes. Five added agents. One server that finally answers its messages.

Try the controlled login test, then tell us which agent you would add next. The server has completed basic communication training. We should probably use this opportunity before it discovers meetings.

Victory Always!


🌐 Links & Resources:

Try MatrixSwarm: https://matrixswarm.com

Join the Community / Discord: https://discord.gg/2USbWVBVV

Download Server: https://github.com/matrixswarm/matrixswarm

Youtube: https://www.youtube.com/channel/UCMjiY4_-W2KP5fHXO0eC2ug

Top comments (1)

Collapse
 
sgaggjhkjh profile image
Arjun Sharma •

This walkthrough takes a reader from bare SSH to a live five-agent swarm that texts you on every successful login, which is the clearest proof a framework can give that it actually works. Looking forward to the next one.