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
| Item | Cost | Purpose |
|---|---|---|
| Domain name | ~$10–15/yr | Your rkt:// address |
| Server | $0–6/mo | Runs your RKT agent 24/7 |
| TLS certificate | Free (Let's Encrypt) | Secure WebSocket (wss://) |
Total Time
rkt://yourdomain.com discoverable by other agentsStep-by-Step
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.
yourname.ai, yourname.dev, or yourname.ioIf 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.
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.
EasiestFly.io
Free tier, global edge, always-on containers.
Free tierDigitalOcean
Full VPS. You manage nginx + TLS yourself.
Most controlRailway (Recommended)
github.com/3289david/rkt-protocol)rkt-protocol. Railway detects Node.js automatically.npx tsx examples/server-example.tsPORT=7749 in Railway's Variables tab.rkt-protocol-production.up.railway.appOr use the Railway CLI:
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
# 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):
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)
# 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:
FROM node:22-alpine WORKDIR /app COPY package*.json ./ RUN npm install COPY . . EXPOSE 7749 CMD ["npx", "tsx", "examples/server-example.ts"]
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",...}
Point Your Domain to the Server
In Cloudflare DNS (dash.cloudflare.com → your domain → DNS → Records), add:
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:
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):
# 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):
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;
}
}
# 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.
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:
The Content (value) of the TXT record — copy this exactly and fill in your values:
v=rkt1 proto=RKTS ep=weather.yourdomain.com port=443 ver=1 cap=weather,forecast,alerts stream=1 evt=1 price=free
| Key | Value | Description |
|---|---|---|
v | rkt1 | Always rkt1 — RKT record version |
proto | RKTS | RKTS = TLS (production), RKT = no TLS (local only) |
ep | your domain | WebSocket endpoint hostname |
port | 443 | 443 for TLS, 7749 for raw TCP |
ver | 1 | RKT protocol version |
cap | comma-separated | Your agent's capabilities |
stream | 1 or 0 | Does your agent support streaming? |
evt | 1 or 0 | Does your agent support event subscriptions? |
mem | 1 or 0 | Does your agent have shared memory? |
price | free | free, usage-based, or subscription |
auth | comma-separated | Auth methods: did,bearer,apikey |
pk | your public key | Optional — 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:
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" // }
Test Your Live Deployment
Test the HTTP health endpoint first:
# 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:
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.
sudo nano /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
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.
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:
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
- ✅ Domain registered on Cloudflare
- ✅ Server deployed (Railway / Fly / VPS)
- ✅ A or CNAME record pointing to server (DNS only, not proxied)
- ✅ nginx reverse proxy configured with WebSocket upgrade headers
- ✅ Let's Encrypt TLS cert installed (
certbot --nginx) - ✅
_rkt.yourdomain.comTXT record added with capabilities - ✅
/.rkt/healthreturns 200 - ✅
wss://weather.yourdomain.com/rktaccepts WebSocket connections - ✅ HELLO → HELLO_ACK handshake works
- ✅ systemd service auto-restarts on crash