<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Rory</title>
    <description>The latest articles on DEV Community by Rory (@rory18439909614).</description>
    <link>https://dev.to/rory18439909614</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4204210%2Ff3d2b937-12a9-454f-8098-b255cc67b9bf.jpg</url>
      <title>DEV Community: Rory</title>
      <link>https://dev.to/rory18439909614</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/rory18439909614"/>
    <language>en</language>
    <item>
      <title>How I Built a Spinning Schulte Table Game</title>
      <dc:creator>Rory</dc:creator>
      <pubDate>Thu, 12 Nov 2026 10:41:46 +0000</pubDate>
      <link>https://dev.to/rory18439909614/how-i-built-a-spinning-schulte-table-game-3f3g</link>
      <guid>https://dev.to/rory18439909614/how-i-built-a-spinning-schulte-table-game-3f3g</guid>
      <description>&lt;p&gt;Every developer has that moment: you're scrolling through X at 11 PM and see someone post a tiny game they made over the weekend. "I could do that," you think. But then Sunday comes and goes, and you never start.&lt;/p&gt;

&lt;p&gt;I decided to stop just thinking about it. Over one weekend, I built Spinning Schulte Table — a brain-training focus game that runs entirely in the browser. No React, no Three.js, no complex build pipeline. Just HTML, CSS, and vanilla JavaScript.&lt;/p&gt;

&lt;p&gt;Here's how I did it.&lt;/p&gt;

&lt;p&gt;What is a Schulte Table?&lt;br&gt;
If you've never heard of it, the Schulte table is a classic focus and attention exercise. You get a grid of scattered numbers, and your goal is to tap them in order: 1, 2, 3, … all the way to the final number. A timer tracks how fast you finish.&lt;/p&gt;

&lt;p&gt;It is widely used for focus training, and even pilots use it to improve peripheral vision and sustained attention.&lt;/p&gt;

&lt;p&gt;My twist: the whole table slowly rotates while you play. Now your eyes have to track numbers on a spinning board, which adds a fun extra challenge.&lt;/p&gt;

&lt;p&gt;The core idea&lt;br&gt;
The game has three core pieces:&lt;br&gt;
Generate a grid — randomize numbers and place them on screen&lt;br&gt;
Rotate the container — run a smooth CSS animation to spin the whole board&lt;br&gt;
Track taps — check whether the player clicks numbers in the correct order&lt;/p&gt;

&lt;p&gt;Let me break each part down.&lt;/p&gt;

&lt;p&gt;Generating the number grid&lt;br&gt;
The simplest approach: create an array of sequential numbers, shuffle it, then render each number as an interactive tile.&lt;/p&gt;

&lt;p&gt;function shuffle(array) {&lt;br&gt;
  for (let i = array.length - 1; i &amp;gt; 0; i--) {&lt;br&gt;
    const j = Math.floor(Math.random() * (i + 1));&lt;br&gt;
    [array[i], array[j]] = [array[j], array[i]];&lt;br&gt;
  }&lt;br&gt;
  return array;&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;function generateNumbers(size) {&lt;br&gt;
  const total = size * size;&lt;br&gt;
  const numbers = Array.from({ length: total }, (_, i) =&amp;gt; i + 1);&lt;br&gt;
  return shuffle(numbers);&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;For positioning, I use absolute positioning inside a square container. Every number tile gets a random position inside the grid boundary, plus a small individual rotation:&lt;/p&gt;

&lt;p&gt;function positionNumber(index, total, containerSize) {&lt;br&gt;
  const angle = (index / total) * Math.PI * 2;&lt;br&gt;
  const radius = containerSize / 2 * 0.8;&lt;br&gt;
  const x = containerSize / 2 + Math.cos(angle) * radius;&lt;br&gt;
  const y = containerSize / 2 + Math.sin(angle) * radius;&lt;br&gt;
  return { x, y };&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;This creates a spiral-like layout instead of a rigid grid, which makes it visually interesting and harder to track numbers.&lt;/p&gt;

&lt;p&gt;The rotation trick&lt;br&gt;
This part was simpler than I expected. I wrapped all number tiles inside one parent container and applied a continuous CSS rotation animation:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;.game-board {&lt;br&gt;
  position: relative;&lt;br&gt;
  width: 500px;&lt;br&gt;
  height: 500px;&lt;br&gt;
  animation: rotate 60s linear infinite;&lt;br&gt;
}&lt;br&gt;
@keyframes rotate {&lt;br&gt;
  from { transform: rotate(0deg); }&lt;br&gt;
  to { transform: rotate(360deg); }&lt;br&gt;
}&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;That’s it. One CSS keyframe animation spins the whole board slowly. Players have to find and tap numbers while everything keeps turning.&lt;/p&gt;

&lt;p&gt;Tracking taps&lt;br&gt;
Each tile listens for click events. When a player taps, we check if this number is the next one in sequence.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;let nextNumber = 1;&lt;br&gt;
let mistakes = 0;&lt;br&gt;
function handleNumberClick(value) {&lt;br&gt;
  if (value === nextNumber) {&lt;br&gt;
    value.classList.add('correct');&lt;br&gt;
    nextNumber++;&lt;br&gt;
    if (nextNumber &amp;gt; gridTotal) {&lt;br&gt;
      finishGame();&lt;br&gt;
    }&lt;br&gt;
  } else {&lt;br&gt;
    mistakes++;&lt;br&gt;
    value.classList.add('mistake');&lt;br&gt;
    setTimeout(() =&amp;gt; value.classList.remove('mistake'), 800);&lt;br&gt;
  }&lt;br&gt;
}&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The timer starts on the first click and stops once you finish all numbers.&lt;/p&gt;

&lt;p&gt;What I learned&lt;br&gt;
Vanilla JavaScript is enough for small browser games. You don’t always need heavy game engines or frameworks. The hardest part was balancing the rotation speed — fast enough to feel challenging, slow enough that players can still read the numbers.&lt;/p&gt;

&lt;p&gt;CSS animations are surprisingly powerful. A single rotation animation creates almost all of the unique feeling of this game.&lt;/p&gt;

&lt;p&gt;It’s easy to overbuild. I skipped multiplayer, save systems, and fancy visual effects. I shipped one core mechanic and polished it until it was fun.&lt;/p&gt;

&lt;p&gt;Try it&lt;br&gt;
The game is live, free to play directly in your browser:&lt;br&gt;
&lt;a href="https://app-8125--rory-desktop-u3f1mn6.uua2a.ai/" rel="noopener noreferrer"&gt;👉 Spinning Schulte Table&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;No download or sign-up required. Open it, tap numbers in order to finish while the board spins. Let me know your best time!&lt;/p&gt;

&lt;p&gt;Note: this demo is hosted locally on my PC, so please be patient if there is a connection hiccup.&lt;/p&gt;

&lt;p&gt;What's next&lt;br&gt;
The game already has adjustable difficulty levels (3×3 up to 10×10) and a leaderboard.&lt;br&gt;
I'm planning to add:&lt;br&gt;
Daily challenges&lt;/p&gt;

&lt;p&gt;If you've built a tiny browser game with vanilla JS, I'd love to hear about it. Feel free to share!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>gamedev</category>
      <category>beginners</category>
    </item>
    <item>
      <title>I built a 3D survival game in a weekend and shipped it from my own PC</title>
      <dc:creator>Rory</dc:creator>
      <pubDate>Thu, 05 Nov 2026 12:07:31 +0000</pubDate>
      <link>https://dev.to/rory18439909614/i-built-a-3d-survival-game-in-a-weekend-and-shipped-it-from-my-own-pc-4l9i</link>
      <guid>https://dev.to/rory18439909614/i-built-a-3d-survival-game-in-a-weekend-and-shipped-it-from-my-own-pc-4l9i</guid>
      <description>&lt;p&gt;I wanted to see how far a weekend build could go, so I made a 3D survival game — dodge incoming fire, and don’t get sandwiched by enemies.&lt;/p&gt;

&lt;p&gt;The whole thing runs on a bare Node HTTP server on my local machine and is exposed via a tunnel. No frameworks, no build steps, just plain ES modules.&lt;/p&gt;

&lt;p&gt;The most fun part was balancing the difficulty. I set a fixed enemy spawn curve at first, but kept dying right around the 2-minute mark. That threshold is when ranged enemies start spawning and damage scaling begins compounding. Once I pushed back when shooters unlock, the curve felt fair instead of cheap.&lt;/p&gt;

&lt;p&gt;My personal best is 4:39. A solid run should last roughly 10–14 minutes. How long can you survive?&lt;/p&gt;

&lt;p&gt;Play it here: &lt;/p&gt;

&lt;p&gt;Feel free to ask me anything about the difficulty tuning or this local hosting + tunnel setup.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>gamedev</category>
      <category>showdev</category>
      <category>webdev</category>
    </item>
    <item>
      <title>The tunnel takes 30 seconds. The permissions take a weekend.</title>
      <dc:creator>Rory</dc:creator>
      <pubDate>Thu, 29 Oct 2026 12:52:12 +0000</pubDate>
      <link>https://dev.to/rory18439909614/the-tunnel-takes-30-seconds-the-permissions-take-a-weekend-1p64</link>
      <guid>https://dev.to/rory18439909614/the-tunnel-takes-30-seconds-the-permissions-take-a-weekend-1p64</guid>
      <description>&lt;p&gt;Most write-ups about exposing an MCP server stop at the step where you get a public URL. That's the easy half.&lt;/p&gt;

&lt;p&gt;The half that actually costs you time is deciding who's allowed to call it — and being able to cut them off without a redeploy.&lt;/p&gt;

&lt;p&gt;If you run an MCP server on your laptop, you've probably noticed it works in Claude Desktop and nowhere else.&lt;code&gt;stdio&lt;/code&gt; transport means the client spawns the process locally. That's fine for one person on one machine, and it stops working the moment a teammate's Agent needs to call your tool, or your phone needs to reach something running on your desk.&lt;/p&gt;

&lt;p&gt;This post walks through five options, what each one actually costs you, and when to pick something else instead. There isn't a single right answer, and the last section covers the cases where none of this applies.&lt;/p&gt;

&lt;h2&gt;
  
  
  What "reachable" actually requires
&lt;/h2&gt;

&lt;p&gt;Before comparing tools, it's worth naming the four things you need:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A stable address — something that doesn't change every time you reconnect&lt;/li&gt;
&lt;li&gt;Transport —&lt;code&gt;stdio&lt;/code&gt; won't work across machines, so you need HTTP or SSE&lt;/li&gt;
&lt;li&gt;Authentication — whoever connects needs to prove they're allowed&lt;/li&gt;
&lt;li&gt;Revocation — the ability to cut someone off without restarting anything
Most tools solve 1 and 2 and leave you to hand-roll 3 and 4. That's where the real work is.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Option 1: ngrok (and similar tunnels)
&lt;/h2&gt;

&lt;p&gt;The default answer. One command and you have a public HTTPS URL.&lt;/p&gt;

&lt;p&gt;ngrok http 3000&lt;/p&gt;

&lt;p&gt;What you get: transport and a stable dev domain, in about three seconds.&lt;/p&gt;

&lt;p&gt;What you don't get:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;One address for everything. Free gives you a single auto-assigned dev domain, and it's the same domain for every service you expose. If you want a separate hostname per service, that's a paid tier.&lt;/li&gt;
&lt;li&gt;Auth is per-endpoint, not per-caller. OAuth and traffic policy work on free (up to 5 MAUs), but the identity is a human account. Two Agents behind the same login look identical, and there's no per-call usage attached to either.&lt;/li&gt;
&lt;li&gt;Revocation is all-or-nothing. You can kill the tunnel, which cuts everyone off at once.
You also need ngrok installed on every machine running a server, and its config is a separate thing to maintain.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For a quick demo this is unbeatable. For anything with more than one caller, it gets thin fast.&lt;/p&gt;

&lt;h2&gt;
  
  
  Option 2: Cloudflare Tunnel
&lt;/h2&gt;

&lt;p&gt;Better on the address problem — you get a stable hostname on a domain you control.&lt;/p&gt;

&lt;p&gt;cloudflared tunnel create my-mcp&lt;br&gt;
cloudflared tunnel route dns my-mcp mcp.example.com&lt;/p&gt;

&lt;p&gt;What you get: stable address, transport, and Cloudflare's auth layer if you wire up Access.&lt;/p&gt;

&lt;p&gt;What it costs: a domain, DNS management, and a Cloudflare account. Cloudflare Access can give you per-user auth, but you're now configuring policies in a dashboard that's designed for corporate SSO, not for "let this one Agent call this one tool."&lt;/p&gt;

&lt;p&gt;It's a solid choice if you already run Cloudflare. If you don't, you're adopting a whole platform to solve one problem.&lt;/p&gt;

&lt;h2&gt;
  
  
  Option 3: Just open a port
&lt;/h2&gt;

&lt;p&gt;Don't. Even with a firewall rule scoped to an IP, you've now got a long-lived inbound listener on a machine that also holds your source code, your SSH keys, and probably an unpatched dependency or two.&lt;/p&gt;

&lt;p&gt;This is the option people fall back to when the others feel heavy, and it's the one that shows up in incident reports.&lt;/p&gt;

&lt;h2&gt;
  
  
  Option 4: Deploy it to a VPS
&lt;/h2&gt;

&lt;p&gt;Move the server off your laptop entirely. Now it's always on, has a real IP, and you can put nginx in front of it.&lt;/p&gt;

&lt;p&gt;The catch is that half the reason the server was local is that it talks to local things — a Postgres instance, files on disk, a GPU you paid for. Moving it to a VPS means moving or tunneling those too, and now you're paying monthly for a machine that idles 90% of the time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Option 5: Outbound-only connection with a stable subdomain
&lt;/h2&gt;

&lt;p&gt;This is the model I ended up using, via a service called UUMit. I'll describe the mechanism rather than the product, because the mechanism is the interesting part.&lt;/p&gt;

&lt;p&gt;The server on your machine opens an outbound connection to a relay. Nothing listens on your machine. Your address is assigned at signup —&lt;code&gt;yourname.uumit.ai&lt;/code&gt; — and stays attached to you even if you move to a different computer.&lt;/p&gt;

&lt;p&gt;Inbound requests arrive through the relay and are pushed down the existing outbound connection. From your firewall's perspective, this is indistinguishable from a browser tab talking to a web server.&lt;/p&gt;

&lt;p&gt;The parts that matter beyond transport:&lt;/p&gt;

&lt;p&gt;Identity is signed. Each machine gets a keypair, and the public card is signed by the platform. A caller can verify that the address they're hitting actually belongs to you, rather than to someone who squatted the subdomain.&lt;/p&gt;

&lt;p&gt;Permissions are per-caller, not per-network. Four levels — off, only me, invite only, everyone — set per exposed service. Opening one thing doesn't open the others.&lt;/p&gt;

&lt;p&gt;Revocation is a state change, not a restart. You flip it, the next request is rejected. No tunnel to kill, no process to bounce.&lt;/p&gt;

&lt;p&gt;Calls can be metered. If you want to charge per call, there's a counter and a settlement path instead of you building a billing table.&lt;/p&gt;

&lt;p&gt;Setting it up is one prompt into your Agent, or one command:&lt;/p&gt;

&lt;p&gt;Install UUMit and claim the address xiaolong&lt;/p&gt;

&lt;p&gt;Then you point it at the services already running locally. The desktop client supports macOS, Windows 10/11, Linux, and Docker.&lt;/p&gt;

&lt;h2&gt;
  
  
  When none of this applies
&lt;/h2&gt;

&lt;p&gt;Three cases where I'd tell you not to bother:&lt;/p&gt;

&lt;p&gt;Your machine isn't always on. A relay can't reach a laptop that's asleep. If your server needs to be up 24/7, put it somewhere that is.&lt;/p&gt;

&lt;p&gt;You need sub-100ms latency. Every hop through a relay adds some. For Agent tool calls this has never mattered to me, but for a real-time game backend it would.&lt;/p&gt;

&lt;p&gt;You're serving thousands of callers. At that point you want a proper load balancer and a real ops setup, not a personal address.&lt;/p&gt;

&lt;p&gt;There's also the honest limitation that this is a young product. If you need an SLA and a support contract, use Cloudflare.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I'd actually recommend
&lt;/h2&gt;

&lt;p&gt;Your situation Use Demo, one-off, nobody else needs it ngrok Already on Cloudflare, want per-user SSO Cloudflare Tunnel Server is stateful and tied to local resources Outbound relay with a stable address Needs 24/7 uptime and an SLA Deploy to a VPS&lt;/p&gt;

&lt;p&gt;The thing I'd push back on is treating "reachable" as the whole problem. Transport is the easy half. Deciding who's allowed in, and being able to take it back without a redeploy, is the half that costs you a weekend if you build it yourself.&lt;/p&gt;

</description>
      <category>mcp</category>
      <category>ai</category>
      <category>security</category>
      <category>selfhosted</category>
    </item>
    <item>
      <title>Giving a local MCP server a public address (without ngrok or a firewall change)</title>
      <dc:creator>Rory</dc:creator>
      <pubDate>Thu, 29 Oct 2026 12:27:55 +0000</pubDate>
      <link>https://dev.to/rory18439909614/giving-a-local-mcp-server-a-public-address-without-ngrok-or-a-firewall-change-m0k</link>
      <guid>https://dev.to/rory18439909614/giving-a-local-mcp-server-a-public-address-without-ngrok-or-a-firewall-change-m0k</guid>
      <description>&lt;p&gt;If you run an MCP server on your laptop, you've probably noticed the same thing I did: it works great in Claude Desktop, and nowhere else.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;stdio&lt;/code&gt; transport means the client has to spawn the process locally. That's fine for one person on one machine. It stops working the moment you want your teammate's Agent to call your tool, or your phone to reach something running on your desk.&lt;/p&gt;

&lt;p&gt;This post walks through the options I tested, what each one actually costs you, and the one that fit my setup. I'm not going to pretend there's a single right answer — there isn't, and the last section covers when you should pick something else.&lt;/p&gt;

&lt;h2&gt;
  
  
  What "reachable" actually requires
&lt;/h2&gt;

&lt;p&gt;Before comparing tools, it's worth naming the four things you need:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;A stable address&lt;/strong&gt; — something that doesn't change every time you reconnect&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Transport&lt;/strong&gt; — &lt;code&gt;stdio&lt;/code&gt; won't work across machines, so you need HTTP or SSE&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Authentication&lt;/strong&gt; — whoever connects needs to prove they're allowed&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Revocation&lt;/strong&gt; — the ability to cut someone off without restarting anything&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Most tools solve 1 and 2 and leave you to hand-roll 3 and 4. That's where the real work is.&lt;/p&gt;

&lt;h2&gt;
  
  
  Option 1: ngrok (and similar tunnels)
&lt;/h2&gt;

&lt;p&gt;The default answer. One command and you have a public HTTPS URL.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ngrok http 3000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What you get: transport and a temporary address, in about three seconds.&lt;/p&gt;

&lt;p&gt;What you don't get:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;A stable address.&lt;/strong&gt; Free-tier URLs change on every restart. Every caller has to be re-told the new one.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Per-caller auth.&lt;/strong&gt; There's one URL. If two people have it, they have the same access.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Granular revocation.&lt;/strong&gt; You can kill the tunnel, which cuts everyone off.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You also need ngrok installed on every machine running a server, and its config is a separate thing to maintain.&lt;/p&gt;

&lt;p&gt;For a quick demo this is unbeatable. For anything with more than one caller, it gets thin fast.&lt;/p&gt;

&lt;h2&gt;
  
  
  Option 2: Cloudflare Tunnel
&lt;/h2&gt;

&lt;p&gt;Better on the address problem — you get a stable hostname on a domain you control.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;cloudflared tunnel create my-mcp
cloudflared tunnel route dns my-mcp mcp.example.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What you get: stable address, transport, and Cloudflare's auth layer if you wire up Access.&lt;/p&gt;

&lt;p&gt;What it costs: a domain, DNS management, and a Cloudflare account. Cloudflare Access can give you per-user auth, but you're now configuring policies in a dashboard that's designed for corporate SSO, not for "let this one Agent call this one tool."&lt;/p&gt;

&lt;p&gt;It's a solid choice if you already run Cloudflare. If you don't, you're adopting a whole platform to solve one problem.&lt;/p&gt;

&lt;h2&gt;
  
  
  Option 3: Just open a port
&lt;/h2&gt;

&lt;p&gt;Don't. Even with a firewall rule scoped to an IP, you've now got a long-lived inbound listener on a machine that also holds your source code, your SSH keys, and probably an unpatched dependency or two.&lt;/p&gt;

&lt;p&gt;This is the option people fall back to when the others feel heavy, and it's the one that shows up in incident reports.&lt;/p&gt;

&lt;h2&gt;
  
  
  Option 4: Deploy it to a VPS
&lt;/h2&gt;

&lt;p&gt;Move the server off your laptop entirely. Now it's always on, has a real IP, and you can put nginx in front of it.&lt;/p&gt;

&lt;p&gt;The catch is that half the reason the server was local is that it talks to local things — a Postgres instance, files on disk, a GPU you paid for. Moving it to a VPS means moving or tunneling those too, and now you're paying monthly for a machine that idles 90% of the time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Option 5: Outbound-only connection with a stable subdomain
&lt;/h2&gt;

&lt;p&gt;This is the model I ended up using, via a service called UUMit. I'll describe the mechanism rather than the product, because the mechanism is the interesting part.&lt;/p&gt;

&lt;p&gt;The server on your machine opens an &lt;strong&gt;outbound&lt;/strong&gt; connection to a relay. Nothing listens on your machine. Your address is assigned at signup — &lt;code&gt;yourname.uumit.ai&lt;/code&gt; — and stays attached to you even if you move to a different computer.&lt;/p&gt;

&lt;p&gt;Inbound requests arrive through the relay and are pushed down the existing outbound connection. From your firewall's perspective, this is indistinguishable from a browser tab talking to a web server.&lt;/p&gt;

&lt;p&gt;The parts that matter beyond transport:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Identity is signed.&lt;/strong&gt; Each machine gets a keypair, and the public card is signed by the platform. A caller can verify that the address they're hitting actually belongs to you, rather than to someone who squatted the subdomain.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Permissions are per-caller, not per-network.&lt;/strong&gt; Four levels — off, only me, invite only, everyone — set per exposed service. Opening one thing doesn't open the others.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Revocation is a state change, not a restart.&lt;/strong&gt; You flip it, the next request is rejected. No tunnel to kill, no process to bounce.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Calls can be metered.&lt;/strong&gt; If you want to charge per call, there's a counter and a settlement path instead of you building a billing table.&lt;/p&gt;

&lt;p&gt;Setting it up is one prompt into your Agent, or one command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Install UUMit and claim the address xiaolong
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then you point it at the services already running locally. The desktop client supports macOS, Windows 10/11, Linux, and Docker.&lt;/p&gt;

&lt;h2&gt;
  
  
  When none of this applies
&lt;/h2&gt;

&lt;p&gt;Three cases where I'd tell you not to bother:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Your machine isn't always on.&lt;/strong&gt; A relay can't reach a laptop that's asleep. If your server needs to be up 24/7, put it somewhere that is.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;You need sub-100ms latency.&lt;/strong&gt; Every hop through a relay adds some. For Agent tool calls this has never mattered to me, but for a real-time game backend it would.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;You're serving thousands of callers.&lt;/strong&gt; At that point you want a proper load balancer and a real ops setup, not a personal address.&lt;/p&gt;

&lt;p&gt;There's also the honest limitation that this is a young product. If you need an SLA and a support contract, use Cloudflare.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I'd actually recommend
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Your situation&lt;/th&gt;
&lt;th&gt;Use&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Demo, one-off, nobody else needs it&lt;/td&gt;
&lt;td&gt;ngrok&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Already on Cloudflare, want per-user SSO&lt;/td&gt;
&lt;td&gt;Cloudflare Tunnel&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Server is stateful and tied to local resources&lt;/td&gt;
&lt;td&gt;Outbound relay with a stable address&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Needs 24/7 uptime and an SLA&lt;/td&gt;
&lt;td&gt;Deploy to a VPS&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The thing I'd push back on is treating "reachable" as the whole problem. Transport is the easy half. Deciding who's allowed in, and being able to take it back without a redeploy, is the half that costs you a weekend if you build it yourself.&lt;/p&gt;

</description>
      <category>mcp</category>
      <category>ai</category>
      <category>security</category>
      <category>selfhosted</category>
    </item>
    <item>
      <title>Testing Lingjing vs Runway vs Pika for my daily workflow</title>
      <dc:creator>Rory</dc:creator>
      <pubDate>Mon, 26 Oct 2026 12:08:08 +0000</pubDate>
      <link>https://dev.to/rory18439909614/testing-lingjing-vs-runway-vs-pika-for-my-daily-workflow-3p8k</link>
      <guid>https://dev.to/rory18439909614/testing-lingjing-vs-runway-vs-pika-for-my-daily-workflow-3p8k</guid>
      <description>&lt;p&gt;I’ve tested these three AI video tools for content creation.&lt;/p&gt;

&lt;p&gt;Pika: Fast &amp;amp; easy for social clips, perfect for quick concepts, weak on long scenes.&lt;/p&gt;

&lt;p&gt;Runway: Great pro editing tools like motion brush &amp;amp; inpainting, but bloated for simple generates.&lt;/p&gt;

&lt;p&gt;Lingjing surprised me: all-modal node canvas, multi-model in one place, great for chaining full projects without tab-switching.&lt;/p&gt;

&lt;p&gt;Core tradeoffs: linear editing vs node pipelines, single flagship model vs multi-model flexibility, niche depth vs end-to-end breadth. Still testing long-form consistency. Which do you prefer for creator work?&lt;/p&gt;

</description>
      <category>ai</category>
      <category>productivity</category>
      <category>tools</category>
    </item>
    <item>
      <title>I found an interesting shift: from C2C physical trading to A2A AI capability trading*</title>
      <dc:creator>Rory</dc:creator>
      <pubDate>Sat, 24 Oct 2026 11:33:03 +0000</pubDate>
      <link>https://dev.to/rory18439909614/i-found-an-interesting-shift-from-c2c-physical-trading-to-a2a-ai-capability-trading-5a79</link>
      <guid>https://dev.to/rory18439909614/i-found-an-interesting-shift-from-c2c-physical-trading-to-a2a-ai-capability-trading-5a79</guid>
      <description>&lt;p&gt;Hi folks,&lt;/p&gt;

&lt;p&gt;I’ve been thinking a lot about marketplaces built for AI agents lately.&lt;/p&gt;

&lt;p&gt;We’re all familiar with C2C secondhand platforms like Mercari, Vinted, and Carousell. These platforms are designed for humans trading physical goods. Their whole workflow revolves around human buyers and sellers: inventory tracking, shipping logistics, and mostly one-off transactions.&lt;/p&gt;

&lt;p&gt;AI agents operate by a completely different set of rules, though.&lt;/p&gt;

&lt;p&gt;What if agents themselves could discover, purchase, and invoke reusable skills automatically?&lt;br&gt;
We’re talking about MCP tools, parsers, workflow modules, dispatch logic — building blocks an agent can call on demand.&lt;br&gt;
Instead of a one-time purchase, creators get paid per API invocation.&lt;/p&gt;

&lt;p&gt;I also ran across the idea of AEO, Agent Engine Optimization.&lt;br&gt;
Where SEO optimizes content to be found by human searchers, AEO focuses on machine-readable metadata. It lets agents automatically match incoming tasks to available capabilities.&lt;/p&gt;

&lt;p&gt;This feels like an entirely new marketplace paradigm, separate from the physical, human-first trading model we’re used to.&lt;/p&gt;

&lt;p&gt;I’d love to get your take on these two questions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Do you think autonomous agents will routinely trade skills with one another in the future?&lt;/li&gt;
&lt;li&gt;What do you see as the biggest practical roadblock for functional A2A marketplaces?&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>agents</category>
      <category>ai</category>
      <category>api</category>
      <category>mcp</category>
    </item>
  </channel>
</rss>
