🚀 Deployment Guide

Deploy Your RKT Agent

Go from local ws://localhost:7749/rkt to a live rkt://weather.yourdomain.com that any agent in the world can connect to. This guide is step-by-step and exact — no handwaving.

What You Need

ItemCostPurpose
Domain name~$10–15/yrYour rkt:// address
Server$0–6/moRuns your RKT agent 24/7
TLS certificateFree (Let's Encrypt)Secure WebSocket (wss://)

Total Time

~10 min
Buy domain + configure Cloudflare DNS
Cloudflare is free for DNS and gives you the fastest propagation
~5 min
Deploy server to Railway or Fly.io
Push your code, get a public URL immediately
~5 min
Point A record + add RNS TXT record
Makes rkt://yourdomain.com discoverable by other agents
~2 min
Test with wscat or client example
Confirm live connection works

Step-by-Step

1

Buy a Domain

Use Cloudflare Registrar — it's at-cost pricing and you get free DNS management bundled in, which you'll need for step 3.

1
Go to dash.cloudflare.com → Domain Registration → Register Domains
2
Search for your name: yourname.ai, yourname.dev, or yourname.io
3
Click Purchase. ~$10–15/yr. Use your real email (you'll get renewal notices).
4
After purchase, Cloudflare auto-sets up DNS for you. No extra steps.
💡

If you already own a domain elsewhere (GoDaddy, Namecheap, etc.), point its nameservers to Cloudflare. Go to cloudflare.com → Add a Site and follow the prompts. Cloudflare gives you two nameservers like ada.ns.cloudflare.com — paste those into your registrar's NS settings.

2

Deploy Your RKT Server

Choose a platform. Railway is the easiest for Node.js. DigitalOcean gives you full control.

Railway

Deploys from GitHub in 2 minutes. No server management.

Easiest

Fly.io

Free tier, global edge, always-on containers.

Free tier

DigitalOcean

Full VPS. You manage nginx + TLS yourself.

Most control

Railway (Recommended)

1
Push your code to GitHub (it's already there: github.com/3289david/rkt-protocol)
2
Go to railway.appNew ProjectDeploy from GitHub repo
3
Select rkt-protocol. Railway detects Node.js automatically.
4
Set the Start command to: npx tsx examples/server-example.ts
5
Set env var PORT=7749 in Railway's Variables tab.
6
Railway gives you a public URL like rkt-protocol-production.up.railway.app

Or use the Railway CLI:

Bash
npm install -g @railway/cli

railway login

# From your project directory:
railway init          # creates a new Railway project
railway up            # deploys immediately

# Set environment variables
railway variables set PORT=7749
railway variables set NODE_ENV=production

# Get your public URL
railway domain        # → rkt-protocol-production.up.railway.app

Fly.io

Bash
# Install Fly CLI
curl -L https://fly.io/install.sh | sh
fly auth signup    # or: fly auth login

# From your project directory:
fly launch         # auto-detects Node.js, creates fly.toml

# When prompted:
#   App name: rkt-weather-agent
#   Region:   nrt (Tokyo) — closest to Seoul
#   Database: No

fly deploy         # deploys in ~60 seconds
fly status         # check it's running
fly logs           # tail logs

Create fly.toml in your project root (Fly generates this automatically but you can also create it manually):

TOMLfly.toml
app = "rkt-weather-agent"
primary_region = "nrt"

[build]

[env]
  PORT = "7749"

[[services]]
  protocol = "tcp"
  internal_port = 7749

  [[services.ports]]
    handlers = ["tls", "http"]
    port = 443

  [[services.ports]]
    handlers = ["http"]
    port = 80

  [services.http_checks]
    interval = "10s"
    path = "/.rkt/health"
    timeout = "2s"

DigitalOcean VPS ($6/mo)

Bash — on your VPS (Ubuntu 24.04)
# Install Node.js 22 LTS
curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash -
sudo apt-get install -y nodejs

# Clone your repo
git clone https://github.com/3289david/rkt-protocol.git
cd rkt-protocol
npm install

# Test it runs
npx tsx examples/server-example.ts
# Should print: "WeatherAgent listening on port 7749"
# Ctrl+C to stop

Docker

Create a Dockerfile in your project root:

DockerfileDockerfile
FROM node:22-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 7749
CMD ["npx", "tsx", "examples/server-example.ts"]
Bash
docker build -t rkt-agent .
docker run -d -p 7749:7749 --name rkt-agent rkt-agent

# Test
curl http://localhost:7749/.rkt/health
# → {"status":"ok","protocol":"RKT/1.0",...}
3

Point Your Domain to the Server

In Cloudflare DNS (dash.cloudflare.com → your domain → DNS → Records), add:

A    weather      →    YOUR.SERVER.IP.ADDRESS ← Proxy status: DNS only (grey cloud, NOT orange) — orange breaks WebSocket
⚠️

Important: Set the Cloudflare proxy status to DNS only (grey cloud icon). If it's "Proxied" (orange cloud), Cloudflare will intercept WebSocket connections and break them. Click the orange cloud icon once to toggle it grey.

So your full domain is: weather.yourdomain.com

Which maps to: rkt://weather.yourdomain.com

If using Railway/Fly instead of a raw VPS, skip the A record and use a CNAME instead:

CNAME  weather      →    rkt-weather-agent.fly.dev ← Use your actual Railway or Fly subdomain here
4

Add TLS (HTTPS / WSS)

TLS is required for production. Without it, agents can only connect via ws://, not wss://. Use nginx as a reverse proxy with Let's Encrypt certificates.

ℹ️

If you deployed to Railway or Fly.io, skip this step — they provide TLS automatically. Your endpoint is already wss://.

On your VPS (DigitalOcean / any Ubuntu server):

Bash
# Install nginx and certbot
sudo apt update
sudo apt install -y nginx certbot python3-certbot-nginx

# Create nginx config for your RKT agent
sudo nano /etc/nginx/sites-available/rkt-agent

Paste this exact config (replace weather.yourdomain.com with your domain):

nginx/etc/nginx/sites-available/rkt-agent
server {
    listen 80;
    server_name weather.yourdomain.com;

    # Health check (plain HTTP — useful for uptime monitors)
    location /.rkt/health {
        proxy_pass http://127.0.0.1:7749;
    }

    # WebSocket proxy — this is the core RKT path
    location /rkt {
        proxy_pass         http://127.0.0.1:7749;
        proxy_http_version 1.1;

        # Required for WebSocket upgrade
        proxy_set_header   Upgrade    $http_upgrade;
        proxy_set_header   Connection "upgrade";

        proxy_set_header   Host       $host;
        proxy_set_header   X-Real-IP  $remote_addr;

        # Increase timeout for long-lived connections
        proxy_read_timeout    3600s;
        proxy_send_timeout    3600s;
        proxy_connect_timeout 10s;
    }

    # Catch all other paths
    location / {
        proxy_pass http://127.0.0.1:7749;
    }
}
Bash
# Enable the site
sudo ln -s /etc/nginx/sites-available/rkt-agent /etc/nginx/sites-enabled/
sudo nginx -t          # test config is valid
sudo systemctl reload nginx

# Get TLS cert from Let's Encrypt (free)
# Replace with your actual domain:
sudo certbot --nginx -d weather.yourdomain.com

# Certbot auto-edits the nginx config to add SSL.
# It also sets up automatic renewal via a cron job.
# Your cert renews every 90 days for free forever.

# Verify renewal works:
sudo certbot renew --dry-run

After certbot runs, your nginx config now serves on port 443 (HTTPS/WSS) and redirects port 80 to 443 automatically.

Your RKT agent is now reachable at wss://weather.yourdomain.com/rkt. TLS is active. Agents can connect securely.

5

Add the RNS DNS Record (Agent Discovery)

This is what makes rkt://weather.yourdomain.com discoverable. Without it, agents must know your WebSocket URL manually. With it, they just need your RKT URI and the protocol resolves everything.

In Cloudflare DNS, add a new TXT record:

TXT   _rkt.weather.yourdomain.com ← The name is always "_rkt." prefixed to your host

The Content (value) of the TXT record — copy this exactly and fill in your values:

DNS TXT Record Value
v=rkt1 proto=RKTS ep=weather.yourdomain.com port=443 ver=1 cap=weather,forecast,alerts stream=1 evt=1 price=free
KeyValueDescription
vrkt1Always rkt1 — RKT record version
protoRKTSRKTS = TLS (production), RKT = no TLS (local only)
epyour domainWebSocket endpoint hostname
port443443 for TLS, 7749 for raw TCP
ver1RKT protocol version
capcomma-separatedYour agent's capabilities
stream1 or 0Does your agent support streaming?
evt1 or 0Does your agent support event subscriptions?
mem1 or 0Does your agent have shared memory?
pricefreefree, usage-based, or subscription
authcomma-separatedAuth methods: did,bearer,apikey
pkyour public keyOptional — Ed25519 public key for DID auth
💡

DNS propagation takes 1–5 minutes with Cloudflare. You can verify the record with: dig TXT _rkt.weather.yourdomain.com

Verify with the RNS resolver:

TypeScript
import { RNSResolver } from "rkt-protocol";

const record = await RNSResolver.resolve("weather.yourdomain.com");
console.log(record);
// {
//   host:         "weather.yourdomain.com",
//   protocol:     "RKTS",
//   endpoint:     "weather.yourdomain.com",
//   port:         443,
//   capabilities: ["weather", "forecast", "alerts"],
//   streaming:    true,
//   events:       true,
//   pricing:      "free"
// }
6

Test Your Live Deployment

Test the HTTP health endpoint first:

Bash
# HTTP health check
curl https://weather.yourdomain.com/.rkt/health
# → {"status":"ok","protocol":"RKT/1.0","agent":"rkt://weather.yourdomain.com"}

# Capability manifest
curl https://weather.yourdomain.com/.rkt/capabilities
# → {"capabilities":["weather","forecast","alerts"],...}

# Install RKT CLI and connect directly
npm i -g rkt-protocol
rkt connect wss://weather.yourdomain.com/rkt
# Or ping it:
rkt ping wss://weather.yourdomain.com/rkt

In the rkt connect REPL, type an intent to test:

Bash — rkt connect REPL
rkt connect wss://weather.yourdomain.com/rkt

✅ Connected! Agent: WeatherAgent/1.0 | Caps: weather,forecast,alerts

> {"intent":"weather.current","params":{"city":"Seoul"}}

← RESPONSE:
{
  "status": 200,
  "data": { "city": "Seoul", "temperature": 24, "condition": "Sunny" }
}

> discover     ← lists all capabilities
> ping         ← measures round-trip latency
> exit

If you get a RESPONSE with weather data, your RKT agent is live and working. Share rkt://weather.yourdomain.com — any agent can now connect.


Keep It Running with systemd

If you're on a VPS, create a systemd service so the agent auto-restarts on crash and starts on boot.

Bash
sudo nano /etc/systemd/system/rkt-agent.service
systemd unit/etc/systemd/system/rkt-agent.service
[Unit]
Description=RKT Agent
After=network.target

[Service]
Type=simple
User=www-data
WorkingDirectory=/home/youruser/rkt-protocol
ExecStart=/usr/bin/npx tsx examples/server-example.ts
Restart=always
RestartSec=5
Environment=NODE_ENV=production
Environment=PORT=7749

[Install]
WantedBy=multi-user.target
Bash
sudo systemctl daemon-reload
sudo systemctl enable rkt-agent    # start on boot
sudo systemctl start rkt-agent     # start now
sudo systemctl status rkt-agent    # check it's running
sudo journalctl -u rkt-agent -f    # tail logs

Environment Variables

Customize your agent via environment variables.

Bash.env (or set in Railway/Fly dashboard)
PORT=7749
NODE_ENV=production
RKT_IDENTITY=rkt://weather.yourdomain.com
RKT_AGENT_NAME=WeatherAgent
RKT_VERSION=1.3.0
RKT_AUTH_REQUIRED=false

Then update your server code to read them:

TypeScript
import { RKTServer } from "rkt-protocol";

const server = new RKTServer({
  port:         parseInt(process.env.PORT ?? "7749"),
  identity:     process.env.RKT_IDENTITY ?? "rkt://localhost",
  userAgent:    `${process.env.RKT_AGENT_NAME ?? "Agent"}/${process.env.RKT_VERSION ?? "1.0"}`,
  authRequired: process.env.RKT_AUTH_REQUIRED === "true",
  capabilities: ["weather", "forecast", "alerts"],
});

Summary Checklist