Skip to main content

Changelog

Notable user-facing changes to noBGP, newest first.

Entries are named after the agent version, which nobgp version reports. Each entry covers one agent release on stable and the router work that shipped with it. Router and agent versions are independent, so the same number in both means nothing.

Entries below 0.4.116 are named after the component that changed.

When a router release adds a tool or a field, reconnect your MCP client to see it. A client keeps the tool list it read when it connected.


0.4.184 — October 2026​

A VPN that comes up no longer silences a node​

  • A node whose route to noBGP moves onto a path that carries smaller packets — a VPN interface coming up under a connection made on the machine's own link — now replaces that connection instead of keeping one that carries nothing. Before, on agent 0.4.183, such a node stayed online while every overlay packet was lost, and only a restart of the agent recovered it. ⚠ Upgrade a machine whose VPN interface has a smaller MTU than its uplink. Details

Sessions survive a gateway that cuts connections by age​

  • Behind an egress gateway that ends a WebSocket connection at a fixed age, the channel that carries traffic to another node and the channel that carries commands, file transfers and terminals are now replaced before the cut, as the control channel already was. A session in flight — an ssh over the overlay, a running command — continues instead of dying until its own deadline. Details

See which of your nodes share a LAN​

  • node_list gives each node a lan, a key into its lans table, and select.lan keeps the nodes on one node's segment, on node_list and on every tool that takes a select. net_peers says same_lan for a peer on the node's own segment, and path for how traffic reaches it today.
  • A node now reports its subnet and its default gateway, so node_list can group two machines on one LAN from what they report rather than from a shared public address. A segment whose nodes all run this release reads basis: "gateway", which is exact. The gateway's MAC address is kept only as a keyed hash, so two homes behind one carrier NAT on the same private range stay apart.

Clearer results​

  • ⚠ An event from a subscription now names its node as node: {id, name}, where it was the id as a string: a script that reads event.node as text must read event.node.id. Details
  • The completion of an fs_grep_subscribe walk reports skipped_files and unreadable_paths, as fs_grep does, so you can tell a search that found nothing from one that could not read a path.
  • When the connection that carried a command closes, the error now tells you to read node_list to see when the node is back.

A root command starts in root's home on OpenWrt too​

  • On a node whose service manager hands the agent a HOME of its own — procd on OpenWrt — a command or terminal that runs as root now has the home that /etc/passwd names, usually /root, and starts there. Before, it had / and started there. Details

Compute nodes​

  • A compute node image now installs the available Ubuntu updates on every agent release, so a machine you provision starts on patched package versions.
  • The base image's own ubuntu account is gone from that image. Your commands run as nobgp or as root, as before.
  • A compute node can no longer reach the cloud host's instance metadata.
Router 0.4.207–0.4.208 · agent 0.4.184

0.4.183 — October 2026​

A result names the account that ran​

  • A result that ran on a node now has user: root (SYSTEM on Windows), or the account that the node's owner configured. You no longer have to infer the account from an absent root_used. Details
  • On Linux and macOS, a command that runs as root now has HOME, USER and LOGNAME, and starts in root's home directory when you give no workdir, as a command that runs as the configured account does. Before, these were empty and the command started in the agent's own directory, usually /. On OpenWrt the command still starts in /, the home the service manager gives the agent.

net_reach says which path a probe took​

  • net_reach now reports interface, the interface the probe left the node by, for example nobgp0, tailscale0 or eth0. A noBGP address in 100.64.0.0/10 is then told apart from a Tailscale address in the same range. net_reach_many shows it on each row.
  • When a name resolves outside the noBGP overlay (a Tailscale, LAN or loopback address), the summary of net_reach and of net_reach_many now says that the probe tested that path, not noBGP's.

Fewer second calls​

  • When a name is shared by several of your nodes, the refusal now gives each node's network and says whether it is online, or since when it is offline.
  • node_list with view: "health" and net_metrics now give the agent version.
  • fs_copy names the node of each end, and service_update names the node of the service.
  • A file call's summary now states the result, for example stat /etc/hosts: file, 312 bytes or delete /tmp/x: deleted.

Clearer refusals​

  • A refusal on a node now writes root: true, the value you send, and no longer the old admin or "true" spellings.
  • When a write cannot replace a file that another program holds open, the error names the file once.
Router 0.4.206 · agent 0.4.183

0.4.182 — October 2026​

A client that reads only text sees your results again​

  • Each tool result again carries a JSON copy of its data as text, beside structuredContent. A client that reads only text, such as claude.ai, now shows your nodes and their fields, not only a count. A copy too large for a model client is shortened in its values, so every field stays. Details

When you say no, the answer names the next step​

  • When you decline a question from your AI client, the answer now says what to do next. For a node name that several of your machines share, it lists each node id to send in place of the name. For a root grant, it names the call that needs no root. Details

Diagnostics answer for IPv6 as well as IPv4​

  • net_reach now also probes the IPv6 answer for a name and reports it in resolution.address6, resolution.class6 and probe6. An application on the node can use either answer, so open for one and timeout for the other is a real finding. Details
  • A node now reports its IPv6 overlay: internal_ip6 in net_peers and slice6 in net_interfaces. net_reach names the resolver that gave a system answer.

ntp_synced agrees with timedatectl​

  • ntp_synced now has the value that timedatectl shows as System clock synchronized. ⚠ On agents 0.4.180 and 0.4.181, a host that runs chrony reported ntp_synced: false for a clock that was in sync. Upgrade such nodes before you compare this field across a fleet. Details

An install never stops at a package question​

  • On Debian and Ubuntu, an install or an upgrade now keeps a configuration file that you changed. It no longer waits for an answer to dpkg's keep or replace question.
  • The install script also completes a package install that an earlier run left half-configured.

A file that another program holds open says so​

  • When a file call fails because another program on the node has the file open or locked, the error now says so, and says that root does not help. You see this mostly on Windows, for example with a database file or a file open in an editor. Details
  • A read of a directory is refused, and the error names fs_list, also on Windows.

A PowerShell script says where it failed​

  • A script with shell: "powershell" now runs from a file on the node. An error names that file and the line in your script, and output and errors arrive in the order the script wrote them. Details
  • A stopped PowerShell command no longer leaves your script in the node's %TEMP%.
  • ⚠ shell: "powershell" now runs only on a Windows node. Another node refuses it and names its OS.
  • ⚠ A Windows script body is now measured against the real cmd.exe limit: about 1.8 KiB of batch or 2.8 KiB of PowerShell. A larger body is refused with its size. Before, it failed on the node with exit 1 and no output. Write a larger script with fs_write and run its path. Details

A network name is unique in its organization​

  • ⚠ Two networks in one organization can no longer have the same name. If a network name is in two of your organizations, the call is refused and gives each network id: send the id. Details
  • An email address has no case: Ada@example.com and ada@example.com are one person for an invitation, an access request or a node transfer.

Subscriptions and cohorts​

  • presence_subscribe now counts offline nodes too. A watch for two machines that are rebooting no longer says matched_nodes: 0. Details
  • ⚠ A cohort that names a node outside the network you named is now refused, and the error says which network each node is in. Before, such a node was included. Details
  • A large subscribe or event_tail result now fits a model client. Events left out of an event_tail result stay in the queue, and next points to the first of them.
  • A call to network_directory or file on MCP now names the tools to use in their place.

A Grok Bot computer installs the version of its own channel​

  • ⚠ ensure.sh now installs nothing when it cannot find out which version the node's channel carries, and it records why in /workspace/nobgp/ensure.log. Before, it installed the stable version. Check the computer's network, then run sudo /workspace/nobgp/ensure.sh again. Details
Router 0.4.204–0.4.205 · agent 0.4.182

0.4.181 — October 2026​

  • sudo nobgp register and nobgp login now print a link that carries its code, so there is nothing to type: https://r.nobgp.com/WDJB for a registration and https://a.nobgp.com/K7QD for a sign-in. Each goes to the same app page as before. Details
  • The QR code comes first, and the link is under it: If the QR code does not scan, open …. There is one small drawing of the code on every terminal, and a default 80×24 window holds all of it. The terminal is no longer asked to grow.
  • On a Linux desktop, sudo nobgp register now opens the browser in the session you already use.

nobgp login stops before the browser where it cannot keep the sign-in​

  • ⚠ Run nobgp login as yourself, never with sudo: the sign-in is kept in the keyring of the user who runs the command. A Linux machine with no desktop session has no keyring; register it with nobgp register --key <key> instead. The command now says so before it opens the browser, so you no longer approve a sign-in that is then lost. Details

Your AI client can ask you before a root grant or a deep delete​

  • A client that supports form elicitation now asks you a question where the call used to be refused: giving someone root on a machine, deleting a shallow directory and everything under it, or naming a node that several of your machines share. You answer in the client, and the call runs with your answer. Details
  • ⚠ For such a client, confirm_root and force are ignored, so a model can no longer confirm a root grant for you. An answer is good for five minutes and for one call.
  • A client that does not support it gets the refusal as before. The refusal now names the node, each address that gets root, and the resolved path, so the client can ask you itself. Details

Every tool input has one name​

  • On MCP, each input now has one name: a node is node (its id or its name), root is root, a session handle is id, a wait is wait, a read position is cursor, a count is limit, and a cohort's filters are under select. The full table
  • ⚠ An old name is refused as an unknown property, and the refusal names the new one. REST keeps the names that the app and the nobgp CLI send.
  • Results use one name each too: the node is node: {id, name}, a command's state is status (running, completed, failed), and admin_used is root_used. Details
  • ⚠ Upgrade the machine you run nobgp exec, nobgp network list, nobgp proxy list and nobgp file from (sudo nobgp upgrade). An older CLI shows an empty result against this router. Details
  • ⚠ A cohort select that names no node now takes only the nodes you own. Send owner: "any" to take every node you may use, as before. Details

You can list your nodes and your session's calls​

  • node_list lists every node you can see, in any network or in none, and is the tool to call first. view: "health" adds each node's health sample, view: "full" its machine, place, identity and services. network_list lists your networks.
  • call_list lists the calls of your own session: what ran, on which node, when, and as root or not. Use it to see what an AI client did for you.
  • network_directory is REST only now. Details

Commands, results and errors​

  • command and command_read take until: "done": the call returns when the command exits, or after 100 seconds with status: "running". Details
  • A result arrives once, as structuredContent with a one-line summary. Details
  • An MCP error now matches the tool's output schema, and an argument your tool list does not know is invalid_args with the same body. Details
  • command_read, command_input and command_signal now name the node that answered.
  • A command_subscribe event carries output as text, each line the exact bytes the command wrote. exit_code is absent on a clean exit. Details

A node reports more of its health​

  • A Linux node now reports temp_c, throttled, failed_units, updates_pending, ntp_synced and ntp_offset_ms, in net_metrics and in node_list with view: "health". ⚠ A field that is absent was not measured: it is never zero or false.
  • node_logs now gives each line the time it was written, in its own time zone. Before, lines from a boot in another time zone came back hours off, and a since bound dropped them.

A new machine takes the place you set for its LAN​

  • A node that registers from the same LAN as machines of your organization whose place you corrected now takes that place (location_source: "site"). A place you set is never changed. Details

A Grok Bot computer keeps its node across an update​

  • On a Grok Bot computer the agent keeps its identity in /workspace/nobgp, and puts itself back after Update Bot's Computer or a restart, as the same node. Setup guide
  • ⚠ apt purge nobgp there removes /workspace/nobgp too, so the machine comes back as a new node. Use apt remove to keep the identity. Details

A client can read what this server is before it connects​

  • GET https://mcp.nobgp.com/mcp/server-card answers an MCP Server Card: the server's name, build and endpoint, with no token and nothing about your account. Details

Security​

  • The router now builds its sign-in and discovery URLs only from the host name it was reached at, never from the X-Forwarded-Host header a caller sends.
Router 0.4.201–0.4.203 · agent 0.4.180–0.4.181

0.4.179 — October 2026​

An MCP client that states a protocol version on every request now sees the node's tools​

  • A client that sends its protocol version with each request — goose does — now gets the tool list from a node's local MCP server. On an agent below 0.4.179 such a client connects and lists no tools at all, so upgrade the node with sudo nobgp upgrade. Details

You can now say where a node really is​

  • A node's controller can set its place with node_location_set, for a machine whose provider registers its address somewhere else — a Starlink household is placed at its exit point, which can be a hundred kilometres away. network_directory then shows that place, with location_source: set, and so does the map in the app. Details
  • The place is rounded to about a kilometre and named by city, state and country. Never send a street address: every member of the organization can read it.
  • node_location_clear goes back to the place derived from the address, which is kept all along.
  • Your own place in whoami follows a node of yours behind the same address: a browser's address is wrong in the same way as the machines beside it.

A planned reconnect no longer looks like a node going away​

  • A node that replaces its own connection before a gateway cuts it, or that moves from WebSocket to QUIC, now publishes no presence events and keeps its online_at, so a watcher sees nothing happen and "how long has this node been up" is the interval it has really been up. Needs agent 0.4.178. Details
  • A node whose previous connection had already died is reported as going offline and coming back, as before. Those reconnects are still counted, as connection.rotations_24h.

A selector's arch now matches the build a node runs​

  • A node selector's arch matches the agent build on the machine, which network_directory now reports as info.build_architecture: an ARM machine with no floating-point unit is armv5, mipsle selects the little-endian MIPS build and mips now the big-endian one only, and a 32-bit agent on a 64-bit kernel is armv7. A node that has reported no build is still matched on what its kernel says. Details
  • ⚠ Re-read any selector you keep that names an architecture: a node used to be matched on what its kernel reports, so a cohort can change. network_directory shows both values per node.

Who turned a node's local MCP server on is on the record​

A paged file read no longer waits for bytes it already has​

  • fs_read and fs_copy now return the bytes an earlier call left behind at once, instead of waiting up to five seconds for the node to send more: paging a file with file_id no longer costs five seconds a chunk, and a copy onto a slow destination no longer runs at half the speed of its link.
Router 0.4.200 · agent 0.4.179

0.4.178 — October 2026​

A command started with detach now really outlives the call​

  • command with detach: true is now honoured by the node: the command starts outside the session and detached_pid comes back with it, so the work survives the session and a stop, restart or upgrade of the agent. Details
  • ⚠ One shape keeps a limit: where the agent runs in a systemd unit without root, a detached command survives the session but still stops when the agent stops, restarts or upgrades. A note on the result says so, so read notes[] before relying on one there.
  • A command that could not start at all comes back with its own exit code — 127 for a command that does not exist — rather than as a successful detach.

noBGP now runs on armv5, MIPS and RISC-V machines​

  • Linux builds are now published for armv5, mips, mipsle and riscv64, so a consumer router, a managed switch or a RISC-V board can be a node. The install script picks the right one for the machine. Details
  • A 32-bit ARM machine with no floating-point unit runs the armv5 build while its kernel still reports armv7l. Through router 0.4.199 a node selector matched it as armv7, what its kernel reports; from router 0.4.200 it matches it as armv5.
  • ⚠ On a MIPS machine whose byte order the install cannot tell, it stops and names the build to install by hand — mips for big-endian, mipsle for little-endian — rather than guessing.

Uninstalling can now remove the node from noBGP as well​

  • sudo nobgp uninstall --purge now tells noBGP the node is gone, so there is nothing left to delete afterwards. Without --purge the identity is kept on purpose and the node stays listed, so a reinstall comes back as the same node. Details
  • It never holds the uninstall up, and anything it could not do is named in the output with the step to take by hand: a compute node belongs to the task that provisioned it, so remove that one with deprovision_node.
  • Removing the package — apt remove, apk del, dnf remove, opkg remove — now runs the uninstall for you, so the service and the agent's DNS and firewall changes go with the package. An upgrade does not. Details
  • ⚠ For a machine where nobgp itself will not run there is now a published uninstaller: curl -fsSL https://downloads.nobgp.com/agent/uninstall.sh | sudo sh, or uninstall.ps1 on Windows. It cannot remove the node from the directory or undo the agent's DNS and firewall changes, and says so. Details

A node comes back about fifteen seconds after a laptop wakes​

  • A machine that was asleep, or a virtual machine its hypervisor had paused, now checks its connection as soon as it runs again and is back in about fifteen seconds, instead of waiting out a deadline of a minute or two. Details
  • Traffic to other nodes comes back with it. Before, it kept failing for about a minute after the node itself was online again.

A peer list now says how the session to each peer is doing​

  • net_peers now reports, per peer, whether a session is carrying its traffic, over which transport, how long it has been up, and the consecutive failures and newest error where it is not. That is what to read when a peer resolves and nothing gets through. Details
  • none on a peer nobody is talking to is the ordinary answer rather than a fault: a session is made when traffic needs one and recycled when it goes idle.

A node now says how its connection ended, and what kind of machine it is​

  • network_directory's node_reason now has a node to report it: clean_stop, upgrade, host_sleep, exit_unrecorded and the rest, beside noBGP's own view of the same close. A sleep, a crash and a cut cable look alike from noBGP's side; the node usually knows which it was.
  • bot, cloud and tailscale are filled in too — the AI-agent sandbox the machine is, the cloud it is an instance of, and whether Tailscale is on it. Each is read on the machine itself, never from its address. Details

A node no longer reloads itself over its own configuration write​

  • A node no longer drops its sessions and its drive for a reload because of a value the agent recorded in its own configuration file — a port it bound, where the drive was mounted. An edit you make is applied within about five seconds, as before.
agent 0.4.178

0.4.177 — October 2026​

A node behind a gateway that cuts connections by age stays online​

  • A node whose control connection is cut at a fixed age — what some corporate egress gateways and cloud egress paths do, measured at about five minutes on one node — now registers again shortly before that age and stays online across the cut. Before, every cut took the node offline for a minute or more and a published service on it answered 502. Details
  • The agent learns the age from the first two cuts on a path, so those two still happen, and re-checks it about every six hours. Keepalives never helped here: the limit is on the connection's age, not on how idle it has been.
  • ⚠ router.control_reconnects in nobgp status then rises by one every few minutes on such a node. That is the new registration, not a flap.
  • WebSocket connections only: a QUIC connection is end to end, and a gateway cannot end it and answer for noBGP.

A node behind a resolver that answers every name no longer claims names that do not exist​

  • A node now tests its own name server before it answers for a LAN name, so one behind a resolver that answers everything — an ISP that sends a name that does not exist to a search page, a fake-IP DNS proxy such as Clash, sing-box or Surge — no longer claims names that only that resolver invented. Before, such a node became your network's answer for every name it was asked about, a browser's random probes and wpad among them. Details
  • A LAN wildcard that points many names at one reverse proxy is unaffected: only an address no LAN host could have is refused, and only in what the node answers for the network. Lookups the node makes for its own applications, and the address it delivers to once it serves a name, are untouched.
  • A name already established this way stops resolving about two minutes after the upgraded node stops claiming it.

A service check now says whether the node's connection keeps dropping​

  • service_check now answers with the node's own connection beside the backend verdict: whether it is up now, and how many times it closed in the last 24 hours, with the newest close and its reason. A backend reachable on a node that drops every few minutes is a service that fails for visitors, and one call now shows both. Details
  • The count is a lower bound and starts empty at this release; an absent count means the history could not be read, which is not the same as none.

A large copy onto a slow destination now finishes​

  • fs_copy now resumes at the next byte when the source sends faster than the destination can write, so a large file across a slow path completes. Before, such a copy failed with resource_exhausted and nothing was written. Details
  • It still refuses, with nothing written, when the source's size or modification time changed during the copy — resuming there would splice two versions of the file into one.

A directory listing too large for a model client now fits, and says what it left out​

  • A network_directory result over MCP that would be larger than a model client accepts is now reduced in steps, and trimmed, omitted_nodes, omitted_networks and each network's nodes_omitted say what is missing. Before, a large fleet's directory was dropped by the client outside the protocol, so you got neither the data nor an error. Ask for fewer nodes — network_name, node_name_glob, os or online — for full detail. Details
  • Its one-line summary is now a sentence. Before, that line repeated the whole directory, which is most of what made the result too large, and it was the last place the old allow_admin name reached an MCP caller.
  • Over REST nothing is trimmed: the full directory is always returned.

A retried command no longer risks running twice​

  • command now takes a retry_key — a key you make for one command. Send the same call with the same key after a failure that returned no result, and a command that already started is not run again: you get its command_id and its output from the first byte. Details
  • ⚠ Where the first call asked the node to start the command and got no answer at all, the key answers with that for an hour rather than guessing. Look on the node before you run the command again, and use a new key when you do.
  • command, command_signal, fs_edit and fs_write now say in their own descriptions what a second call does, beside the tools that already did. Details

A command can now keep running after the call​

  • command now takes detach: true for work that must outlive the call — a server, a watcher, a script that restarts the agent itself. The call returns at once with detached_pid, and the command survives the session and a stop, restart or upgrade of the agent. Details
  • Its output does not come back — stdin, stdout and stderr are the null device, so redirect inside the command with absolute paths to keep it. detach together with input or stdin: "open" is refused: a detached command cannot be fed.
  • ⚠ The node half ships in agent 0.4.178. On a node below it, detached_pid is absent, a note says the command ran attached to the session, and the per-platform recipes are still the way.

A node's recent connection history says whether it keeps dropping​

  • network_directory now carries each node's connection: how often its connection closed in the last 24 hours, when and why the newest close happened, when noBGP last heard from it, whether the host restarted across it, and the node's own account of how it ended. It appears only on a node that actually dropped, and it survives brief. Details
  • A planned reconnect is counted apart, as rotations_24h, and is never reported as the newest close — a node behind a gateway that cuts connections by age replaces its own connection several times an hour while nothing is wrong.
  • A noBGP release no longer counts as a close on the nodes it was serving, so the count is the node's own drops.
  • service_check carries the same four new fields beside its backend verdict.
  • info.health now carries stale: true when a connected node's sample stopped refreshing, so a reading that describes the host minutes ago is no longer read as now. The sample is marked, never withheld: a node reconnecting faster than it samples is the one most worth reading.

A routing table or peer list can now be narrowed, and fits when it is large​

  • net_routes now takes a destination: an address returns the routes that cover it, the default route included; a CIDR returns the routes inside it and the routes that carry it; and 0.0.0.0/0 or ::/0 returns one address family. Details
  • A net_routes or net_peers result over MCP larger than a model client accepts is now reduced — host routes and stale peers go first — with trimmed and omitted_routes / omitted_peers saying what is missing. Before, a large table was dropped by the client outside the protocol, so you got neither the routes nor an error. Details
  • Over REST nothing is trimmed.

More architectures in a selector, and what kind of machine a node is​

  • A node selector's arch now takes armv5, mips and riscv64. mips matches either byte order, because that is all the kernel reports.
  • network_directory now reports bot, cloud and tailscale per node — the AI-agent sandbox the machine is, the cloud it is an instance of, and whether Tailscale is on it. Each is read on the machine itself and never from its address, so a node reaching the internet through a cloud NAT is not reported as being in that cloud. Details
  • Present and empty means the node looked and found none; absent means its agent is too old to look.
Router 0.4.198–0.4.199 · agent 0.4.177

0.4.176 — October 2026​

A node behind a proxy that answers for noBGP now reconnects on its own​

  • A node on the WebSocket transport now closes its control connection and reconnects within about a minute and a half when the router stops answering — including where something between them goes on answering noBGP's own keepalives, which a corporate egress gateway or an inspecting proxy does. Before, such a node showed offline in noBGP while nobgp status on the machine read router.connected: true, for hours, until somebody restarted the agent. Details
  • The agent asks the router for an answer only the router can give, and only while the channel has been quiet, so a channel carrying traffic sends nothing extra and a router too old to answer never has its connection closed.
  • QUIC connections are unchanged, and need nothing: nothing in the middle can answer for the router there.
Router 0.4.197 · agent 0.4.176

0.4.175 — October 2026​

A program writing firewall rules at the same moment no longer costs a Linux node its own rules​

  • On a Linux machine, every firewall command the agent runs now waits up to five seconds for the kernel's xtables lock — the lock Docker, Tailscale, k3s and firewalld take while they write rules. Before, a command that found it held failed at once, so a node could start without the accept rule for its own overlay interface and connections it made to peers then timed out on a machine whose other rules drop the overlay range. Details
  • A node that stops or upgrades while another program holds that lock now still tries to remove its own chain when it could not check that the chain was there, and says so in its log. Before, a check that hit the lock read as no chain, and the chain could be left behind with nothing in the log.
  • ⚠ On the legacy iptables 1.8.9 and 1.8.10, which wait for the lock on their own, a firewall command can now fail after five seconds where it used to wait longer; the agent logs that. A build too old to accept the wait is detected and runs as before.

A published service no longer logs an error when a client leaves​

  • A machine serving a published service now logs a client going away at debug. Before, every disconnection was an error — on one machine, one every 15 seconds — which buried the machine's real faults in node_logs with min_level: error. Details
  • A machine restarting for an upgrade no longer logs an error for a service connection it is closing itself. Agent 0.4.149 covered reads on those connections; this covers writes. If a noBGP deployment ends the connection, that is a warning, not an error.

A save made by renaming one file over another reaches the shared drive​

  • On a Linux node, writing a temporary file and renaming it over the real one — how git updates a ref and how most editors save — now lands on the shared drive. Before, the first such save landed and every later one was set aside as a conflict while noBGP kept the earlier version, with the program told its save had succeeded. ⚠ Check anything written this way against the copy you expect, a git repository on a share included. Details
  • chmod on the drive now carries the new mode to noBGP, so a script keeps its exec bit instead of the change living on one machine. It re-sends the file, since a mode travels only with a file's bytes. ⚠ Other nodes still show 0644: a directory listing carries no mode yet. Details
  • Creating a file under a name the share will refuse — one noBGP reserves, or a second spelling of a name the directory already holds — now fails on the create call rather than reporting success and losing the bytes at the upload. Details
  • ln on the drive now says hard links are not supported, where it used to report that the file being linked from did not exist. Details
agent 0.4.173–0.4.175

0.4.172 — October 2026​

Each MCP tool now does one thing​

  • Every operation of the file super-tool has its own MCP tool: fs_fetch_url, fs_lock and fs_unlock join the seven per-op fs_* tools and fs_copy. Details
  • command starts a session, and command_read, command_input and command_signal carry it on. Reading a session's output is a read-only call now, so a client that decides on annotations no longer sees it as a write.
  • ⚠ file is gone from MCP, and command no longer takes command_id, signal or output_offset on MCP or REST. Reconnect your client and use the tools above. POST /api/v1/tools/file still serves all thirteen operations — including op=batch, which has no MCP spelling — and the flat body at /actions/execute_shell_command still carries command_id.
  • ⚠ Over MCP only the new names exist. Send root where you sent admin (admin is refused), and read root_used, allow_root and can_root where you read admin_used, allow_admin and can_elevate. REST still takes and returns both names. Details
  • Each tool carries a display title, and its annotations were re-derived: a tool is marked destructive unless it only ever adds something, and the nine tools that reach outside noBGP say so. Details
  • A feedback_submit report is now at most 1000 characters, and describes the tool rather than the task — no prompts, file contents or command output.

A node grant's targets now narrow which peers the node reaches​

  • ⚠ node_grant with targets stores them. A grant you narrowed before this release carries no restriction and reaches every peer its owner may use — send node_grant again with the targets you want. Details

An MCP response carries the answer and no diagnostics​

  • ⚠ An MCP result no longer carries call_id or duration_ms, and an MCP error no longer carries call_id. If your client reads them, read them from the REST surface, which still returns them. A plan-limit refusal over MCP no longer carries the link to the billing page; the message still names the limit. Details
  • feedback_submit now attaches the call a report is about by itself: name the tool and noBGP adds your last call of it. call_id is a REST-only parameter there; a client whose tool list predates this has the field dropped and its report filed, rather than the call refused.
  • A tool whose second call repeats its effect says so in its own description — a second provision_node for a name whose machine is running starts a second paid machine, a second command_input sends the text again. Details
  • Each MCP tool now declares the sign-in it needs, for a client that builds its consent screen from the tool list. It declares only: the bearer token is checked on every call as before. Details

A firewall that drops the overlay range no longer leaves peers unreachable​

  • On a Linux machine the agent now asks the kernel whether a reply from its own overlay range reaches it, and where a firewall rule drops it the node takes its slice from 172.16.0.0/12 or 10.0.0.0/8 instead and starts its overlay again. Details
  • ⚠ That move renumbers every peer's overlay address on the machine. Names are unaffected; anything pinned to a raw overlay address there — a script, a firewall rule of your own — is not. nobgp show reports the new slice.
  • The log names the one firewall rule that keeps the slice in 100.64.0.0/10, for a machine that has to stay there. A rule that drops more than that range leaves the node with the warning and the slice it has, since no second move is made.

Another program's routing rule no longer takes the overlay​

  • On a Linux machine, peers are now reachable when another program's routing rule sends noBGP's whole address range to a routing table of its own — the layout of a VPN exit node. The agent installs a rule that keeps the range on the overlay, and puts it back within a minute when a program that manages the machine's rules removes it. Details
  • The agent installs that rule only on a machine where the whole range is taken. Where another product routes one single address inside noBGP's range — one of its own peers — that product keeps it, as before.
  • When the rule is in and the range still goes elsewhere, the agent's log says the overlay does not work on that machine instead of reporting a repair.

A node reconnects when the machine's route to noBGP moves​

  • A node whose route to noBGP moves to another interface — a VPN exit node turned on or off, a change of uplink, a cable in place of Wi-Fi — now reconnects in less than half a minute. Before, it was unreachable for up to two minutes. Details
  • A connection that still works on the new path is kept, so relay sessions and commands running on it are not interrupted.
  • When the agent closes its connection for such a move, it also asks the channels that carry commands, file transfers and terminals, and remakes the ones that do not answer on the new path.
  • A route that moves back and forth every few seconds no longer restarts the agent: at most two such reconnects are made in ten minutes.
  • A node that lost a QUIC attempt while a VPN exit node held its route no longer stays on the WebSocket fallback for up to an hour after that VPN is gone. Details

A name server that does not answer no longer keeps a node offline​

  • A node whose machine has a name server that never answers now registers anyway: the agent tries the addresses it last connected to, and public DNS, beside that lookup rather than after it. Before, such a node logged a timed-out lookup of noBGP's own name for minutes. Details
  • A name server that is slow and works still wins, so a machine whose second one answers after a few seconds keeps resolving through it.
  • The agent now keeps the noBGP addresses it has connected to on disk, so a node restarts and registers on a machine where no name server answers at all. Before, a new process began with none of those addresses and the node stayed offline. Details

The agent keeps its DNS line in a resolver file that another overlay product writes​

  • On a Linux machine where another overlay product generates /etc/resolv.conf, the agent now puts its nameserver line back as soon as that product writes the file again. Before, it did so once a minute, and some lookups of peer names failed in between. That product may report that its file was changed. Details
  • The agent no longer takes such a file over, and does not write it when it stops.
  • ⚠ Where the resolver of that product has noBGP as its only upstream, the machine has DNS only while the agent runs. The log of the agent now names that state once, with how to end it.
Router 0.4.195–0.4.196 · agent 0.4.172

0.4.166 — October 2026​

The firewall order is repaired as soon as another program changes it​

  • On a Linux machine, the agent now checks the order of the iptables INPUT chain within a second of the machine getting a new interface or a new address, and not only once a minute. A VPN or a firewall manager that starts and puts its own drop rule ahead of noBGP's takes connections to peers down for about a second, where before they were down until the next check. Details
  • These extra checks have a budget, so a machine that gets a new interface every few seconds — one starting containers in a loop — reads INPUT about twice a minute rather than continuously.

You can invite a person to an organization from an AI client​

  • org_invite_create is now an MCP tool. When node_access_grant refuses a person who is not a member, the refusal gives the organization id and says who can invite.

The audit log records each change to who can open a service​

  • Each service_share call that adds, removes, approves or rejects a visitor now writes a row in the audit log of the organization. A read of the list writes a row only for a root terminal.
Router 0.4.192–0.4.194 · agent 0.4.166

0.4.165 — October 2026​

An upgrade on a Debian node with little memory now completes​

  • On a Debian or Ubuntu node with little memory, an upgrade of the agent could stop before the end, or install the agent and then report install_failed. The agent now installs its package without the package lists of the distribution, which uses much less memory and time. The upgrade to this version can still show the old error. Later upgrades do not. Details
  • When a dependency of the agent is not installed, the agent installs again with the package lists, as before.

The log says when a node tries QUIC again​

  • When a node does not get QUIC, the line in its log now says when the node tries QUIC again: when QUIC answers again or at the next reconnect, or after one hour on a network that the agent marked as UDP-blocked. Before, the line said only "until the next reconnect". Details
Router 0.4.191 · agent 0.4.165

0.4.162 — October 2026​

A node goes back to QUIC by itself​

  • A node that connected over WebSocket (wss) because QUIC did not answer in time now goes back to QUIC when QUIC answers again. Before, it stayed on wss until its next reconnect. nobgp status shows the transport. Details
  • A slow DNS answer when the agent starts no longer uses the time that the node has to connect over QUIC.
  • When a node does not get QUIC, its log now says why.

An agent restart on OpenWrt does not interrupt DNS on the LAN​

  • On an OpenWrt router, a restart or an upgrade of the agent no longer restarts dnsmasq. Before, each one stopped DNS for the whole LAN for a moment. Details

net_metrics counts the UDP that an overloaded node drops​

  • When a peer sends UDP faster than a node delivers it, the node drops the excess. net_metrics now counts these datagrams in deliver_failed and return_full of datapath_drops. Before, they had no count. The count of dropped replies (return_full) is on Linux only. Details
Router 0.4.191 · agent 0.4.162

0.4.161 — October 2026​

The overlay moves off a range that another product owns​

  • When one route of a machine covers all of 100.64.0.0/10 (Tailscale, or carrier-grade NAT from the internet provider), the agent now takes its /20 from 172.16.0.0/12. When the machine already uses that range, it takes a free /20 of 10.0.0.0/8. It no longer takes a /20 inside the route, so a Mac with Tailscale reaches all its Tailscale peers again. A Mac or a Windows machine behind carrier-grade NAT now starts with its overlay. Details
  • The agent also moves its /20 when another product has a route inside it.
  • ⚠ A Mac or a Windows machine with Tailscale that ran 0.4.160 gets a new /20 at the first start on this version. So does a Linux machine directly on carrier-grade NAT, when the provider's route covers all of 100.64.0.0/10. Their overlay addresses change and their names do not. If you saved an overlay address of such a machine, use its name, or read the new address.
  • ⚠ The agent sees only the routes of the machine. If the new /20 covers a private network that the machine reaches through its default gateway, set overlay-cidr to a /20 clear of it. overlay-cidr now accepts a /20 of 100.64.0.0/10, 172.16.0.0/12 or 10.0.0.0/8.
  • A node starts without an overlay only when all three ranges are claimed. nobgp status then names the three ranges. Details

Parallel downloads through a node do not pause​

  • Several downloads at the same time from a node, or from a host that the node reaches for you, no longer pause and start again while the connection has room.
Router 0.4.190 · agent 0.4.161

0.4.160 — October 2026​

A Mac with Tailscale keeps its overlay​

  • A Mac that started the agent while Tailscale was connected had no noBGP overlay. No name of your network resolved on it, not even its own, and it reached no peer. nobgp status reported that the address range was fully claimed. The agent now takes its /20 and starts with its overlay, and Tailscale keeps working. The same fix applies on macOS and Windows to any product that routes all of 100.64.0.0/10 through one route. Details
  • The cause: the agent read Tailscale's route to all of 100.64.0.0/10 as a claim on every range it could use. macOS and Windows send traffic to the most specific route, so the agent's own /20 wins over that route.
  • ⚠ Traffic to a Tailscale peer whose address falls inside the agent's /20 now goes to noBGP. This machine no longer reaches that peer. To prevent this, set overlay-cidr to a /20 clear of those addresses.
  • ⚠ A Mac or a Windows machine whose default gateway is inside a route that covers all of 100.64.0.0/10 (carrier-grade NAT) still starts without an overlay, as before.
Router 0.4.188–0.4.189 · agent 0.4.160

0.4.159 — October 2026​

The flag is --root​

  • nobgp exec, nobgp shell, nobgp proxy publish and nobgp proxy update take --root, the same word the tool surface and Roles & Permissions use. --admin still works and is hidden from --help. ⚠ Giving both names in one call is refused, as sending both fields to noBGP is. Details

A Linux machine running another overlay VPN reaches its peers​

  • Connections that a Linux machine makes to its noBGP peers now get past another product's drop rule in the iptables INPUT chain. When that product restarts and puts its rule first again, the agent moves its own rule back to the top within one minute. ⚠ A product that drops in its own nftables chain still blocks them. Details
  • This opens nothing to a peer. A peer's traffic has reached the machine as a local connection since 0.4.144, so the rule only covers the replies the machine itself asked for.

A Synology serves its whole log​

  • node_logs on a Synology DSM node now reads the file DSM writes for the agent, instead of the few lines its journal still holds. Such a node reports source: "syslog" with a path beside it. Details
  • ⚠ DSM keeps the older generations of that file compressed, and node_logs does not read compressed files. A page that reaches the beginning of the live file names them in unreachable; read them on the NAS with xz -dc.

A reply has to come from the port the connection used​

  • A reply to a connection that a machine opens to a peer is now accepted only from a port that the connection sent to. Of the packets that come back, only an accepted reply keeps the connection's address open. Details
  • ⚠ A program that asks a peer over a protocol that answers from a different port than it was asked on no longer gets the answer. TFTP is the one in common use.

Where a node is, and what it runs​

  • network_directory now reports the approximate place of each node's public address and the provider that the node uses: city, state, country, latitude, longitude, accuracy_radius, asn, as_org, isp and connection_type. The place is the place of the address, not of the machine. ⚠ isp and connection_type come from licensed data: read the licence before you show them on a page of your own. Details
  • network_directory takes an os filter: linux, darwin or windows.

Commands and files​

  • A command session now ends when the node's connection to noBGP closes, for example when the agent restarts. The next call answers target_unreachable, which is not retryable on this session, and the output that arrived stays readable for five minutes. ⚠ When the node's connection is on another noBGP instance than the session, the session still answers running until the one-hour idle reap. Details
  • A large fs_write no longer reports a timeout for a write that the node completed: noBGP waits longer for a larger file. ⚠ A timeout on the last call does not mean that the write failed. Check with fs_stat before you send the file again.
  • A large fs_write no longer holds up the machine's other calls while noBGP finishes the write.
  • Over /mcp, a field sent at the wrong level of a call is refused with a message that says where the field belongs. Details
  • A tool call on /api/v1/tools/ or /actions/ whose arguments carry a URL with an IP address, such as a file op=fetch_url from a LAN mirror, is no longer refused with 403.

Installing on Windows​

  • The Windows install command now ends in Invoke-Expression: in the app, in register_node and on these pages. ⚠ Microsoft Defender can refuse the old command, which ends in iex, with Access is denied. Change that word to Invoke-Expression in your own notes and scripts. Details

Billing​

  • The included amount of a month is now what your allowances hold for that month. An allowance that lasts more than one month, such as the launch promotion, no longer counts in full in each month. Details

In the app​

  • A service or a pending upgrade of a node that comes online shows without a reload of the page.
  • The graph has a map view. Show Map in the side menu draws your nodes on a map, each at the approximate place of its public address. The map comes from OpenFreeMap. While the map is open, your browser gets the map images from tiles.openfreemap.org. That service sees your browser's public IP address and the part of the map that is in view. ⚠ The map opens on the places of your nodes, so that part shows approximately where they are. The service does not get the names or the addresses of your nodes.
  • Usage over time shows one bar for each day, with a printed scale and your allowance as a dotted line.
  • The notice of a larger allowance says how much of the extra allowance is left.
Router 0.4.187 · agent 0.4.159

0.4.158 — September 2026​

Signing in and registering​

  • nobgp login and nobgp register now follow your organization's SSO rule. An organization that requires SSO refuses a sign-in from the terminal that does not use it, as the browser already did.
  • nobgp register no longer stops with register failed (401): invalid token when the sign-in saved by nobgp login has expired. It renews it, and when noBGP still refuses it, it continues in the browser. Details
  • nobgp list now asks for your password with sudo, as nobgp status and nobgp show do, instead of saying that it cannot read the profile directory. On Windows, run it from an Administrator prompt. Details
  • The QR code of nobgp login and nobgp register is black and white, on every terminal. When the window is too short for the full-size code, the terminal is asked to grow, and macOS Terminal does. A terminal that keeps its size gets the smaller code.
  • After you approve a machine in the app, its node page opens when the node is online, instead of showing it offline until you reload.
  • ⚠ Registering or signing in through the browser needs agent 0.4.153 or newer. An older agent is refused before anybody signs in, and the page says to upgrade. Run sudo nobgp upgrade -f on that machine (on Windows, nobgp upgrade -f from an Administrator prompt), or register it with a key, which is unaffected. Details

Security​

  • A network's enrollment key no longer enrolls a machine in place of a provisioned node while its task runs. A provisioned container enrolls with its own one-time grant.
  • The file tools refuse a path that starts with two slashes or backslashes, such as a Windows network share \\server\share, with a message that says why.

Billing​

  • Turning automatic refill off, or lowering its amount, now also applies to a refill that was about to start: noBGP no longer buys credit at the old setting in that moment. Details

On the machine​

  • A published service no longer keeps a connection open on the machine after that connection ended at noBGP.
  • The node log no longer writes a line for each proxied connection that noBGP closes.
  • A recursive file list names a folder it cannot read once, with the error, instead of twice.
  • A command, a file call, a browser terminal or a published service whose first attempt met a node that could not reach noBGP now succeeds when the retry does.

In the app​

  • The service form and the terminal list say root (administrator on Windows), not administrator.
  • After you change to a different organization, the invite list shows only the invites of that organization.
Router 0.4.185–0.4.186 · agent 0.4.158

0.4.157 — September 2026​

This release brings the new permission model. Roles & Permissions states the rules in one place.

Permissions​

  • A node is controlled by its owner and by the organization's Owners and Admins. These are the node's controllers. A Member now renames, configures, labels, publishes services on, stops and deletes the nodes and networks they own, and transfers the nodes they own. ⚠ A Member can no longer stop, deprovision or delete another person's node. Details
  • ⚠ Being in the organization no longer lets you run commands on every node. You use a node when it is shared with the organization, or when a controller puts you on its access list. Every network that existed before is shared (Org), so nobody loses access. Details
  • A network is Org (the default) or Private. A node follows its network, or is set to Private (you and org admins). A node is never more open than its network. Set it in the app, with network_update and node_access_set, or when you create the node: in the app's registration page, and with access on provision_node. Details
  • Each node has an access list. Its controllers name members at use or root, and a member can ask with node_access_request. There are six tools: node_access_list, node_access_set, node_access_grant, node_access_revoke, node_access_request and node_access_decide. Details
  • ⚠ A revoke, or a node that stops being shared, takes effect at the next call, and the member's running commands stop. It does not undo what the member did on the machine: an SSH key, a scheduled job or a tunnel stays.
  • network_directory tells you what you hold on each node, in my_access: control, root, use or none.
  • Root is a separate grant. The controllers have it. Anyone else gets it from a root entry, which needs confirm_root: true after a warning, or from a name on a root terminal, in that terminal only. Sharing never gives root. A node whose owner set allow-root: false refuses root to everyone, controllers included. Details
  • "Elevated" is now called root everywhere. On Windows, root means administrator. The fields are root, root_used, allow_root and can_root, and the machine setting is allow-root. The old admin names still work. ⚠ Do not send both names of one field in one call: that is invalid_args. ⚠ On the machine, where both allow-admin and allow-root are set, the stricter value applies. Details
  • Any member can create a network, and owns it. The network's owner or an Admin sets its name, channel, Org or Private, client isolation and members may add nodes (on by default).
  • Client isolation: in a network with isolated: true, the nodes do not reach each other. Who may use or control each node does not change. Details
  • ⚠ Only the network's owner or an Admin reads, creates, disables or deletes an enrollment key. There are four tools: network_key_list, network_key_create, network_key_update and network_key_delete. Another member gets install commands with no key from register_node: they sign in, and they own the node.
  • ⚠ Deleting a network never deletes a node. A network that still has a node is refused, and the refusal names each node to remove first with node_delete.
  • node_transfer gives a node to another member of its organization, named by email. The result lists each root grant that the new owner inherits.
  • node_channel_set sets the release channel of one node.
  • When a member leaves or is removed, the networks and nodes they owned move to an Owner. Nothing is deleted, and the result lists what moved. Details

Services and terminals​

  • ⚠ A service with sign-in no longer opens for every member. It opens for the node's controllers and the addresses on its list. To open it to the whole organization, set all_org_members with service_update. A member who is refused can click Request access. Details
  • ⚠ A terminal is never public. It always needs sign-in.
  • Only the node's controllers publish, change, share or delete a service on it.
  • A name on a root terminal is a root grant, in that terminal only. It takes exact addresses, and naming anyone who is not a controller needs confirm_root: true. Removing the name closes the terminal for that person. Details
  • An open terminal is checked again while it runs. It closes when the person's access is withdrawn.

Logs, support and the audit log​

  • ⚠ Reading a node's agent log needs control of the node: its owner, or an Owner or Admin. A use or root entry does not give it, and neither does sharing. Anyone at the machine can read it with nobgp service logs. Details
  • node_logs reads the log as the agent itself. It needs no root: "true" retry, and it works on a node with allow-root: false. The logs domain of allow-tools still turns it off. Details
  • Your organization decides whether noBGP support may act in it. "Allow noBGP support" is on by default. An Owner or Admin can turn it off, and give staff temporary access when you want help. Details
  • Staff never control your nodes, except that they read a node's agent log and read or change its remote configuration. The node still refuses its own settings, allow-root included. Every staff action, and every staff attempt that noBGP refuses, is in your audit log. In the app, each such row carries a noBGP support chip, which says what allowed the action.
  • ⚠ Only the Owner sees money data: invoices, the card, the credit balance and the spend cap. An Admin still sees the plan and the interval. Details
  • The member list is for Owners and Admins. Only the invited person can accept an invite: the sign-in address must match the invited address.
  • Audit log search by q also finds the actor's name. A call that fails over MCP records its error code. Details

A node's local MCP server​

  • node_grant turns a node's local MCP server on or off. It acts for the node's owner, with the owner's current rights at each call. ⚠ The observe tier is gone: a node that had it is off until a controller turns it on. Details
  • ⚠ Anyone who can run on the node can call its local MCP server, and reach what the node's owner may reach.
  • The machine's owner can refuse it: sudo nobgp config --local-mcp=off. Details

Registering a machine, and signing in​

  • nobgp register and nobgp login print a page and a four-character code. Type the code at app.nobgp.com/register (a machine) or app.nobgp.com/activate (nobgp login), or scan the QR code, which carries both. The code is good for five minutes and one entry. Details
  • ⚠ Enter the code signed in as the account that must own the result. The terminal names the account that entered the code and the account that approved it, so you can press Ctrl-C if it is not yours.
  • The approval page names the machine: its hostname, platform, agent version, public address and approximate place. A Deny ends the command and says so in the terminal.
  • A terminal always shows a QR code, in half blocks where the window is small. ⚠ Where the terminal cannot show colour, the code uses the terminal's own colours. On a dark terminal it is inverted: a phone camera reads it, but some desktop scanners do not.
  • A node enrolled again with the network's key after it lost its key file comes back as the same node, when the network's owner owns it.

On the machine​

  • ⚠ allow-tools refuses a value it cannot read. A value that is not a domain leaves the node serving nothing, and nobgp config refuses it. logs is a new domain, added once to a profile that lists its domains. Check yours with nobgp show. Details
  • sudo nobgp config --peer-loopback=false keeps ports bound only on the machine's loopback off the network. The default is unchanged. Details
  • ⚠ The config directory is closed to other accounts. On Windows, run nobgp commands that read it from an Administrator prompt. On Linux and macOS, root owns it, so those commands need sudo.
  • A value that you save with nobgp config stays saved. Before, a value saved during a registration or a restart could be lost: if you set allow-root: false or another owner setting at such a time, read it back with nobgp show. A lock file (.default.yml.lock) now sits beside the configuration file. Details
  • nobgp mcp install says who can use the local MCP token, and writes each client configuration 0600. Details
  • install.sh does not downgrade an agent that is ahead of the stable channel. Set NOBGP_VERSION to install a specific version. Details

Fixes​

  • fs_copy and transfer URLs follow a symlink to a regular file. ⚠ A recursive copy does not follow links inside the folder: each link is a failed row. Details
  • fs_list and fs_stat entries carry a type. An absent type means unknown, not file. Details
  • fs_read refuses a folder, a pipe, a socket or a block device at once, instead of blocking.
  • net_reach says a name is not resolved yet when the lookup is still running, instead of saying it does not resolve.
  • A late poll of a command says when it exited, with its exit code. Details
  • A command session that closes stops its whole process group.
  • Deleting a file on the shared drive removes it on noBGP, also right after a write of it.
  • A file call that names a shared drive you cannot see answers not_found.
  • Bare peer names on an OpenWrt router recover within a minute when other software removes the search suffix. Details
  • On Ubuntu, an upgrade finishes without needrestart restarting the agent in the middle of it.
  • A missing path is no longer logged as an error on the node, and answers not_found on a Windows node in any language.
  • In the app, Show Offline works when every node in a network has been offline for a long time.
  • The app opens on your own personal organization, not on another person's personal organization that you were invited into.
Router 0.4.178–0.4.184 · agent 0.4.152–0.4.157

0.4.151 — September 2026​

A recursive listing no longer reports a folder it could not read as empty​

  • fs_list with recursive: true no longer answers empty for a folder that is missing, that it cannot open, or that is not a folder at all. It now fails with not_found, permission_denied, or an error naming the path as not a directory — the same answers the call without recursive already gave. Details
  • ⚠ Code that reads a zero-entry recursive listing as an empty folder now has an error to handle. file with op: "list" answers the same way.

A shared drive that fails to mount on a Mac or Linux says so​

  • A webdav mount attempt that runs and fails is no longer reported as the host having nothing to mount with. nobgp status names the failure under fs.error, and the machine says it will retry. Details
  • A mount that keeps failing now writes a warning each cycle rather than one line.

Find the machine that can run the job​

  • network_directory now filters on what a machine has: min_cpu_count, min_total_memory (in bytes), gpu_kind and has_gpu, composing with the filters already there — so which of my machines has a CUDA card and at least 32 GB is one call rather than the whole fleet pulled into context and sifted. Details
  • ⚠ A machine that has not reported a field never matches, in either direction, so read an empty result as none reported rather than none exist — a machine whose agent predates the GPU probe is invisible to has_gpu both ways. Call without the filter and read the capacity fields yourself while a fleet is mid-upgrade.
  • Filters that could only ever return nothing are refused instead: a negative min_cpu_count, or has_gpu contradicting gpu_kind.

Cancelling renewal stops automatic credit purchases at once​

  • Cancelling a subscription now clears the organization's auto-reload rule immediately. Before, it went on buying credit until the period ended. Your plan still runs to the end of the period you paid for, credit you already hold is untouched, and buying credit yourself is unaffected. Details
  • Your credit maximum is kept until the subscription actually ends, so an Owner can arm a new rule for the rest of the period — and a rule saved after the cancellation is left alone.

A copy can no longer take a name noBGP reserves​

  • fs_copy onto the shared drive or a machine's storage area now refuses a destination named .nobgp-trash or .nobgp-upload-…, as every other way onto those trees already did. Before, such a copy stored a file that no listing shows, nothing bills and no client can delete. Details

The audit log records the last kind of call that was missing​

  • Continuing a command or file session is now recorded even when a different noBGP instance than the one holding the session answers it. Details
  • A file entry says whether it touched a machine's storage area or the machine's own disk, and a copy entry names its source end as well as the destination it changed. Details

Smaller things​

  • A machine's log no longer says its connection to noBGP was lost when the agent is closing that connection itself, restarting in place — a container, or an agent running in the foreground.
Router 0.4.177 · agent 0.4.151

0.4.149 — September 2026​

An upgrade no longer writes errors for its own shutdown​

  • A machine upgrading no longer logs an error for closing its own connections or for its own agent exiting, so node_logs with min_level: error shows real faults. Agent 0.4.146 covered the connection to the router; this covers a machine's service and peer connections and the agent exit as well.
agent 0.4.149

0.4.148 — September 2026​

An upgrade replaces the supervisor on a Mac​

  • An upgrade now restarts the whole service on macOS, so the background supervisor launchd starts comes up on the new program too instead of keeping the old one until the Mac reboots. Agent 0.4.147 did this on every other machine with a service manager. Details
  • ⚠ The upgrade to this release still replaces the agent alone on a Mac, because the version already running makes that decision. Run sudo nobgp service restart on the Mac, or let the next upgrade do it.
  • nobgp service restart no longer leaves a Mac without a service when launchd reports the restart as failed. The agent waits for the old supervisor to exit, starts the service itself, and tries the start up to three times.
agent 0.4.148

0.4.147 — September 2026​

A LAN device whose name is not a host name is reachable​

  • You can now reach a device whose DHCP name holds a space or other characters a host name cannot — a speaker leasing as WiiM Mini-9D84 answers to WiiM-Mini-9D84. The machine running the LAN's DHCP server reads its own leases and serves the device under that label. Details
  • A real name still wins: the leases are the last source a machine looks at, after its hosts file, LAN DNS and mDNS. Only dnsmasq's leases are read, and only on the machine serving DHCP.
  • net_reach on that machine reports the device's own name as resolution.lan_name, so an answer says which host it reached.
  • The machine owner's lan-names list is asked on the label and on the device's own name, so either excludes it.

A WebDAV drive no longer replaces another machine's newer version in silence​

  • A save through a webdav mount is now checked against the version that machine read. One noBGP refuses reaches the operating system's client as 412 Precondition Failed, the other machine's version stays on the drive, and your bytes are kept on the node — nobgp status lists them under fs.conflicts, and a later save of the same file clears them. Open the file again, merge and save. Details
  • ⚠ It covers less than the other backends do: the check is per file rather than per open, and only for files that machine read through the agent. An editor whose file an indexer or preview pane has since read, a save made by renaming a temporary file over the document, and a file the client had already cached are all still last-writer-wins. What it does not cover

A hung mount no longer leaves a machine reporting a drive it does not have​

  • A mount attempt that does not finish within two minutes is now stopped and reported as a failure, on every backend, and the machine retries. A machine whose mount helper hangs no longer goes on publishing the backend it had, with no drive under it. Details
  • nobgp status names such an attempt under fs.error, and no new attempt starts until the stuck helper has gone.

An upgrade replaces the supervisor on more machines​

  • An upgrade now restarts the whole service on Synology DSM, OpenWrt, OpenRC and sysv init as well as on systemd and Windows, so the background supervisor comes up on the new program too instead of keeping the old one until the machine reboots. Details
  • ⚠ The upgrade to this release still replaces the agent alone, because the version already running makes that decision. Run sudo nobgp service restart on such a machine, or let the next upgrade do it.
  • A machine now writes one warning in its log when it finds its supervisor running a program file that has since been replaced.
  • nobgp service restart no longer leaves a sysv machine stopped when the shutdown takes longer than the init script waits for it.
  • On Synology DSM, nobgp service restart run through noBGP now restarts the service. Before, it refused, because DSM has no systemd-run. Details

Free space where your commands actually run​

  • net_metrics now reports home_disk_free_bytes beside disk_free_bytes: free space on the filesystem holding the home directory an unelevated command starts in. On a machine with /home on its own storage that is a different disk from the one disk_free_bytes measures.
  • network_directory carries it too, in each machine's info.health, so one call ranks a whole fleet by where work would land.
  • It is absent rather than zero where the machine did not measure it — on Windows, on Synology DSM, and where no account is configured for unelevated work. A zero is a measured full disk.

A machine with no drive mounted no longer reports one it can read​

  • mount_readable in network_directory is now withdrawn together with fs_mount, so a machine with nothing mounted shows neither and the two read as one answer. Before, mount_readable kept the last value the machine sent, so one whose drive had gone went on reporting true beside an absent fs_mount until it mounted again. Details
  • Machines running an agent older than 0.4.85 are left alone: those cannot report the field, and their silence is not a withdrawal.

A LAN name stays put while the machine serving it reconnects​

  • A machine keeps the LAN names it serves for two minutes after its connection ends, so an agent restart, a Wi-Fi blip or a noBGP deployment no longer moves a name onto another machine and back. A lookup landing in that window used to pick a different machine — a different session key — and hold it for a whole lease. Details
  • ⚠ A machine that has really gone therefore keeps the name for those two minutes on top of the five-minute lease.

A tool list one release old can still use a new list field​

  • An MCP client that has not refetched its tool list can now send a new array field as a JSON-encoded string, and noBGP decodes it — so paths on fs_copy works from a client whose cached list predates it, instead of failing every call for the session. A string that is not a JSON array is refused with the spelling that works. Details
  • ⚠ A new integer or object field on an existing tool still needs a refreshed tool list; reconnecting your client is what does it.

Three kinds of call reach the audit log​

Self-hosted routers​

  • ⚠ Run router 0.4.176 or later before your machines reach agent 0.4.147. An older router does not know resolution.lan_name or home_disk_free_bytes and refuses the whole answer rather than dropping the field, so net_reach and net_metrics return an error for those machines.
Router 0.4.176 · agent 0.4.147

0.4.146 — September 2026​

What a node dropped from a peer is counted​

  • net_metrics now counts five more kinds of dropped packet in datapath_drops: protocol, icmp_type, malformed, no_delivery and deliver_failed. They cover what another node sent to this machine's own services that the machine did not deliver. Details
  • A packet for a LAN name the machine no longer serves is counted as deliver_failed rather than dropped uncounted.
  • ⚠ A self-hosted router must run 0.4.174 or later before its machines run this agent, or net_metrics returns an error for them.

A healthy node no longer reads as error while it mounts​

  • info.fs_backend in network_directory now reports only a mount attempt that has finished. Before, a node published error before each attempt and its real backend up to 90 seconds later, so a machine whose drive was fine read as failed in between.
  • A node remounting keeps its last backend until the new attempt concludes, and info.fs_mount is withdrawn meanwhile — so a backend with no mount point beside it reads as "mounting". ⚠ info.mount_readable is not withdrawn with it: it keeps the value the node last reported until the node reports again, so during a remount it can still say true about a mount that has gone. Read fs_mount for that, not mount_readable.

A new file shows its real size in dir and Explorer​

  • On a winfsp or nfs mount, a directory listing now shows the size of a file this machine has written and not yet uploaded. Before, dir, Explorer and any backup tool comparing sizes read a new file as 0 KB while Get-Item on the same name was right. Details

An old nobgp.com service URL reaches the service again​

  • A https://<name>.nobgp.com URL for a service you published now redirects permanently to https://<name>.nobgp.link, keeping the path and the query, so an old bookmark or a link you shared arrives. A GET gets a 301 and any other method a 308, which keeps the body. ⚠ The redirect is a migration aid and will be removed with the old host — update the links you control. Details
  • A name under nobgp.com that has never been a published service now returns 404. ⚠ Before, such a host reached noBGP's own endpoints and https://<name>.nobgp.com/health answered 200 OK, so an uptime check pointed at an old service URL stayed green while the service was unreachable — point it at the nobgp.link URL.

Smaller things​

  • A machine's log no longer says a stop was not asked for when the stop was its own upgrade restart.
  • A router deployment now writes a warning in each machine's log instead of an error, and says the node is reconnecting.
Router 0.4.175 · agent 0.4.146

0.4.145 — September 2026​

Published services have a domain of their own​

  • A published service is now served at https://<name>.nobgp.link. It is a separate domain from the nobgp.com the dashboard and the API use, so a page your service serves can no longer write a cookie the dashboard reads. Details
  • ⚠ <name>.nobgp.com no longer reaches a service. Your services and their names are unchanged, but their URLs are not: update bookmarks, shared links, third-party OAuth redirect URIs and any allowlist naming the old host. Read the current one from public_url.
  • ⚠ Your backend now receives cookies named workos-access-token, workos-refresh-token, workos-session-id and nobgp-user-id. noBGP never sets those on the new domain, so one of that name is yours. Details
  • ⚠ A path under /.nobgp/ on your service's host is the router's and does not reach your backend. Move anything your app serves there.
  • The cookie noBGP sets on your service's host is named __Host-nobgp_sid. A browser accepts that name only from the host itself, so another service on nobgp.link cannot set one for yours. Your backend receives neither it nor nobgp_sid.
  • A service you publish is still not isolated from the other services on nobgp.link: a page on one can set a cookie of its own that every other one receives.
  • Your service's own pages can sign a visitor out of that service alone, with a POST to /.nobgp/auth/logout. ⚠ The visitor stays signed in to noBGP, so the next protected page of that service signs them in again with no click. Signing out of the noBGP app still signs them out of every service.
  • Several tabs of one service can sign in at the same time.

Registering a Mac asks for the grant its drive needs​

  • sudo nobgp register on a Mac now opens System Settings on Privacy & Security › Full Disk Access and names the row to switch on, "nobgp" (/usr/local/bin/nobgp). It applies to the running agent at once, and the node's file tools can then read its own drive. Details
  • It asks whenever the command's output goes to a terminal, so the install script with NOBGP_KEY asks too. An enrolment whose output is not a terminal — an MDM, a script logging to a file — does not ask.
  • It never fails the registration, and says nothing when the grant is not needed. The window opens on the screen of the person who ran the command, so sudo nobgp register over SSH opens nothing on anyone else's.
  • On a Mac that is already enrolled, run sudo nobgp register at the machine for the same offer, or grant it by hand.

The browser registration page suggests the name you set​

  • The page now suggests the name this machine would have chosen — --name, then node-name in the configuration file, then NOBGP_NAME — and falls back to the hostname. ⚠ Since 0.4.132 it suggested the hostname whatever you had set, and the page's answer wins, so curl … | NOBGP_NAME=web-1 sh enrolled the machine under its hostname. Rename such a node. Details

A node delivers what it can from its own socket, and drops the rest​

  • A node no longer puts a peer's packet on its tunnel adapter. It carries TCP, UDP and ping — including an IP fragment of one, which is new — and drops another IP protocol, ICMP other than ping, and a packet it cannot read. A peer never got a reply for those anyway. Details
  • ⚠ windows-firewall: respect-windows now filters nothing from another node. Through 0.4.143 it still covered what arrived on the tunnel adapter.
  • ⚠ A node whose socket delivery did not start now drops every packet a peer sends it, instead of falling back to the tunnel adapter. nobgp status reports network.peer_access: none (socket delivery did not start …) and the node's log says why.

A published service cannot point at the agent's own ports​

  • A node refuses to open a connection to its own local MCP server, shared-drive proxy, NFS server, overlay DNS server or Windows agent API for a published service, and to port 111. The first request fails with permission_denied naming the socket, and service_check shows the same reason. Details
  • A target on another machine on the node's LAN is unaffected, apart from port 111.

Memory and disk figures you can act on​

  • A node now reports the memory available to start new work, as mem_available_bytes in network_directory's info.health and in net_metrics. Free memory, which older agents report as mem_free_bytes, reads near zero on a healthy Mac and about four times low on Linux.
  • network_directory now reports info.total_disk, the usable size (used plus available) of the filesystem disk_free_bytes measures, so free space can be read as a proportion. 180 MB free is a full disk on one machine and an idle one on another.
  • That free-space figure is measured where the agent's own program file is. On a NAS this keeps the question off a data volume, which would have to spin its drives up to answer it.
Router 0.4.172–0.4.174 · agent 0.4.144–0.4.145

0.4.143 — September 2026​

Uploads through a node keep moving​

  • Several uploads at once to a service on a node, or to a LAN device that a node serves, no longer pause for seconds under load, and a new connection to the same node opens promptly during them.
  • net_metrics now counts two more kinds of dropped packet in datapath_drops: return_full and queue_full. The node must run agent 0.4.142 or later.

Copy a directory or a set of files in one call​

  • fs_copy takes recursive: true to copy every file under a directory, or paths to copy named files, in one call. A call copies at most 256 files, and a recursive copy at most 1 GiB. The result lists each file, and complete is true only when every file was copied. This works with every agent version.
  • ⚠ A symlink in the tree is copied as the file it points to. Do not copy a tree that holds a FIFO or a device node.

A Linux agent starts without permission to create a TUN device​

  • On AWS Fargate, Cloud Run, Azure Container Instances and a Kubernetes pod without NET_ADMIN or /dev/net/tun, the Linux agent now starts without the overlay instead of stopping. command, the file tools and nobgp status work, and nobgp status says why there is no overlay.
  • The agent no longer turns on the host's IP forwarding, so it also starts in a container whose /proc/sys is read-only. ⚠ A host where an older agent turned it on keeps that setting: turn it off yourself if it was off before you installed noBGP. Details

Smaller things​

  • On macOS, a service that listens only on an IPv6 link-local address, for example on en0, is reachable from peers.
  • net_peers shows each peer's agent version (agent_version) and whether traffic to it stays IPv6 (ipv6_wire). The node must run agent 0.4.142 or later.
  • whoami lists the tools you can call and their arguments (tools), so a client with an old tool list can see what it is missing.
  • node_logs on OpenWrt says when a page reaches the beginning of the system log's ring buffer, the time of the ring's oldest line, and where the agent keeps its own copy of its log.
  • A file operation that noBGP asks for again after a lost reply now runs once and reports the work it did: fs_delete no longer reports no such file or a refusal for a file it deleted, and a slow write no longer fails. Details
  • ⚠ A transfer: "url" upload URL for the shared drive or a node's storage area needs the token you called the tool with, which a shell usually does not hold. Write to the node itself, or send the bytes inline.
  • The address shown for a node and on the registration approval page is the address the load balancer saw. A client cannot set it with an X-Forwarded-For header.
  • On Windows, an update restart lets the agent finish its own shutdown instead of stopping it by force.
  • A transport-family setting now also applies to the node's noBGP mount and to the CLI.
  • A reinstall of the same version no longer restarts the agent when nothing changed. nobgp upgrade <version> -f still restarts every profile.
  • On macOS, a failure to write the firewall anchor no longer stops the agent.
  • The OpenWrt installer checks the package contents before it writes to /, and opkg remove nobgp removes the package directory.
Router 0.4.170–0.4.171 · agent 0.4.142–0.4.143

0.4.141 — September 2026​

A peer reaches a node's services as a local process​

  • A peer that connects to a node by its name now reaches that node's services as if it were a local process on the node. A service that listens on 127.0.0.1, on [::1], on the wildcard or on any other local address is reachable. So you can keep a service on loopback and still reach it through noBGP. Details
  • The service sees a local client. TCP, UDP and ICMP echo are carried, and a ping to the node is answered by the node itself.
  • The agent's own listeners, rpcbind on port 111 and Unix domain sockets stay local to the node.
  • ⚠ The host firewall does not filter this traffic. ufw, firewalld, the macOS firewall and Windows Firewall do not apply to it, and windows-firewall has no effect on it. A service that trusts any local client, for example Redis with no password, the Docker API on a TCP port or an admin page with no login, is now open to every node and user that can reach the node. What to do
  • nobgp status and nobgp show say that the host firewall does not filter peers. network_directory now also lists a host service that listens on loopback only.
  • A port with nothing listening answers at once: TCP with a reset, UDP with the ICMP error. A UDP port that is closed to peers answers administratively prohibited.
  • The agent version that counts is the one on the node that runs the service. An older agent keeps the old behaviour.
  • ⚠ On macOS, a service that listens only on an IPv6 link-local address is not reachable yet (agent#1271).

Downloads through a node or a LAN name keep moving​

  • Several downloads at once from a service on a node, or from a LAN device that a node serves, no longer stop for seconds on a slow or relayed path. Measured over a relay, no stream paused for longer than about 1.5 s.
  • A slow peer no longer holds up the other peers of the same node.
  • ⚠ An upload to a node through this path can still pause for 2 to 6 s under load (agent#1270).

You can see why a node did not update​

  • network_directory shows an update that a node was offered and has not installed (info.upgrade). When the node says why, the reason is there too, for example auto_upgrade_off or install_failed. The node must run agent 0.4.140 or later to send a reason.
  • The app marks a node that was offered an update and has not installed it.
  • A node below its channel's minimum version is now updated when it connects, not refused. It stays out of the overlay until it updates, and the MCP tools still reach it. version_status reads below_floor.
  • When such a node has not updated after an hour, its owner gets one email for that version. ⚠ No channel has a minimum version above 0.3.0 today, so this email does not go out yet.

A LAN device with only an IPv6 address can be reached​

  • A node now reaches a LAN device that it serves over IPv6 as well as IPv4, so a device that has only an IPv6 address is served by a node that has a route to it. An mDNS lookup asks for both addresses, so such a device is also found. Details
  • A Windows node answers a ping to such a device, and net_reach on a Windows node can send an ICMP probe to an IPv6 address.
  • Traffic to a peer's IPv6 overlay address stays IPv6 when both nodes run agent 0.4.140 or later. It is not translated to IPv4 and back. Details

Smaller things​

  • A copy to a read-only file system fails with failed_precondition and names your path. fs_copy and fs_grep_subscribe always say what failed at the end that failed.
  • A fs_grep or fs_grep_subscribe path that is absolute only on another platform, for example /etc/os-release on a Windows node, is reported as not_found for that path, and that node completes its search. Before, the search failed on that node.
  • A refused fs_edit is no longer written to the node's log as an error.
Router 0.4.168–0.4.169 · agent 0.4.140–0.4.141

0.4.139 — September 2026​

A LAN name now resolves on the machine that serves it​

  • A machine that reaches a device on its own LAN now answers its own lookups of that name with the device's LAN address. On Ubuntu and other systemd-resolved hosts the name used to fail on that one machine, while every other node resolved it through it. Details
  • Only the machine next to the device needs the upgrade. A device that has an IPv6 address alone, on a node with no IPv6 overlay address, is still answered not found.
  • ⚠ net_reach reports such a name as source: "overlay" with the class of the LAN address (usually class: "lan"), where it used to report source: "system".

Smaller things​

  • A Windows machine no longer counts its own NetBIOS broadcasts as dropped replies in net_metrics, or writes a warning about them every minute.
  • After you approve a registration in the browser, the next sudo nobgp register prompt now takes the answer you type. It could wait for ever.
  • The agent's log is ASCII, so it reads correctly in Windows PowerShell 5.1.
agent 0.4.139

0.4.138 — September 2026​

Peer names now resolve over IPv6 as well as IPv4​

  • Every machine takes an IPv6 overlay slice beside its IPv4 one, so a peer's name answers AAAA as well as A. The two addresses reach the same peer. Details
  • Nothing on the network changes: the traffic still leaves as IPv4, so a peer on an older agent needs no upgrade, and there is no new port, endpoint or firewall rule.
  • On a machine whose IPv4 slice is full, a newly discovered name gets an IPv6 address and resolves AAAA only. A LAN name, and a machine's own name for itself, stay IPv4-only.
  • A host that cannot take a slice keeps running on IPv4 and says why in nobgp status. Turn it off with overlay-ipv6: false, on the machine or with node_config_set. Details
  • ⚠ A reply grows by 20 bytes when it crosses families. This is not measured on macOS or Windows. If large UDP replies go missing there, lower mtu or turn the setting off.

Every machine now serves the names on its own LAN​

  • macOS and Windows members now carry a peer's traffic to a device on their LAN — a printer, a NAS, a speaker — with nothing to set. Details
  • ⚠ That path carries TCP, UDP and ICMP echo only, over IPv4, on Linux too. Anything else addressed to such a name is dropped.
  • ⚠ A Linux member adds no firewall rules for this any more, and removes those an earlier release added: the NOBGP_<interface>_NAT and NOBGP_<interface>_FWD chains, the matching OpenWrt fw4 rules, and the firewalld binding of the noBGP interface to the trusted zone.
  • ⚠ The lan-delivery key is retired. The agent removes it from the profile, and --lan-delivery and NOBGP_LAN_DELIVERY are gone.
  • A machine sending to a member that no longer serves a name moves to one that does within seconds, on the same address. Details
  • A name the serving member can no longer reach stops resolving about two minutes after it stops answering. A slow mDNS device keeps its name, and an offline member keeps the names it serves. ⚠ Upgrade the machines that serve such devices. Details
  • A device on your own LAN is reached directly on IPv6 as well as IPv4. Details

Traffic that was lost now crosses noBGP​

  • A UDP service bound to 0.0.0.0 or :: — the default for most daemons — now answers. Details
  • DNS, NTP and other traffic on well-known UDP ports, IPv6 packets with extension headers, IPv6 ping and ICMP parameter problem now cross intact.
  • Other IP protocols — GRE, ESP, SCTP, tunnels — reach the far node, but their replies do not come back.
  • A packet a machine cannot handle is dropped on its own. It no longer stops the agent or ends the connection to that peer.
  • net_metrics now reports datapath_drops, the overlay packets a machine refused, by class. ⚠ A non-zero panics count is an agent bug. Please report it.
  • ⚠ A self-hosted router must run 0.4.165 or later before its machines run this agent, or net_metrics returns an error for them.

Registering a machine finishes in the browser​

  • sudo nobgp register prints the sign-in link as a QR code, so you can enrol a machine with no browser from your phone. Details
  • It offers two ways to register: the browser link, or a registration key pasted at the prompt. A pasted key is not shown as you type.
  • The page you approve names the machine, and you pick the organization, the network and the node name there. When the name is taken, the page offers a free one.
  • ⚠ Where the name belongs to an offline node, approving can take that node over — its node ID, labels, role grants and storage area. The page asks you first.
  • In a container, register and the install script now say that no service runs the agent. With NOBGP_EXIT_NO_SERVICE=1, that case exits 4.
  • sudo nobgp register and nobgp login say a browser opened only when one did, and on Windows the sign-in link reaches the browser whole.

Peer names resolve on the first try on Alpine​

  • On Alpine Linux and other musl machines, the first lookup of a peer's name now succeeds. The agent is the only nameserver in /etc/resolv.conf there. Details
  • ⚠ While the agent is stopped, such a machine has no DNS. A restarting agent restores the machine's own file first, so an agent that crashed no longer leaves the machine without DNS.

Smaller things​

  • A machine whose host refuses systemd's --pipe upgrades again. ⚠ If a node showed an old version while online, upgrade it once. Details
  • An OpenWrt machine now answers AAAA for a peer's name.
  • ⚠ On Windows, nobgp service restart inside a command session now refuses and names the ways through. Before, it printed scheduled and nothing restarted: restart a node you restarted that way from the machine itself. Details
  • nobgp register no longer freezes in a background shell, and a command that ends without an exit no longer stalls the machine.
  • input sent while another call closes the same session's stdin is written first, or refused with invalid_args. Details
  • A Mac no longer counts its own broadcasts as dropped replies in net_metrics.
  • network_directory lists a host service whatever case its type is spelled in, and a source word noBGP cannot use costs only that field, never the service itself.
Router 0.4.157–0.4.167 · agent 0.4.129–0.4.138

0.4.128 — September 2026​

You can ask a node whether it reaches a name​

  • net_reach resolves a name on one node and probes what it got back, and says which resolver answered and which node delivers it. It replaces the ping and nc recipes, and answers the part those cannot.
  • net_reach_many asks every node a selector matches, up to 64 of them, and returns a rollup — how many answered, how many did not resolve it, how many are offline — with one row per node.
  • Both are available to a node's own local server at the read-only observe tier.
  • A result says when a name resolves through the overlay but the node's own applications cannot resolve it — the failure that otherwise looks healthy. Details
  • A node answers this from agent 0.4.128. ⚠ An older agent comes back unsupported, naming the node. Upgrade that agent, or fall back to command.

A command that reads stdin now finishes​

  • A command session's stdin is at end of file unless you ask for a pipe, so ausearch, cat with no file, ssh and anything else that reads stdin ends instead of waiting for ever. Details
  • ⚠ A shell or REPL you mean to feed now needs stdin: "open" in the session, or an input on the call that starts it. Without one it exits immediately.
  • close_input puts stdin at end of file, optionally with a final input on the same call, which is what makes sort and wc usable.
  • A node honours this from agent 0.4.128. ⚠ An older agent keeps the open pipe it always had: the new default does nothing there, and close_input comes back without stdin_closed. Upgrade the agent, or stop such a session with SIGKILL.

A device that only announces itself on the LAN can be reached by name​

  • A member now finds a device whose name exists only over mDNS — most speakers, printers, smart-home hubs and KVM appliances announce themselves that way and appear in no DNS zone — and serves it to the rest of the network. Details
  • Names that exist only over LLMNR or NetBIOS are still not found.

You choose which names on a machine's LAN it serves​

  • sudo nobgp config --lan-names 'nas*,printer' limits which host names on a machine's own LAN it will resolve for the rest of the network. *,!router serves everything but one device, and off serves none. The default is any name, which is what earlier releases did. Details
  • Names the machine's own applications look up are never filtered, and there is no remote path to the setting — it is the machine owner's say over their own LAN.
  • A name outside the list is never resolved for the rest of the network, and net_reach reports it as resolution.refused: "lan_names". ⚠ A remote caller can still tell that such a name exists on the machine's LAN, from the shape of the refusal. It never gets the address.

A LAN name is claimed only by a member that can deliver it​

  • A member that cannot carry the traffic no longer claims the name, so noBGP falls through to one that can. Details
  • ⚠ A device whose only route into the network was through a macOS or Windows member stops resolving once that member upgrades. Neither platform can forward that traffic, so such a member now says nothing rather than claiming a name it cannot deliver. Reach the device from the segment it sits on, or give it a Linux member.
  • Traffic now also reaches such a device through a member whose firewall drops forwarded traffic — OpenWrt's fw4 and firewalld included. ⚠ On a firewalld host the agent puts the noBGP interface in the trusted zone at runtime, which also lets your peers reach ports on that host itself.
  • A member puts those firewall rules back when a firewall reload removes them, and stops claiming names while it cannot.
  • Where several members reach one device, noBGP now prefers an online member that can forward the traffic. A macOS or Windows member is used only when nothing else claims the name. Details
  • Such a name is now re-confirmed every five minutes rather than every hour, so a member stops sending traffic to a gateway that has gone offline sooner.

The directory can show what a node's host shares on its LAN​

  • network_directory carries each node's info.host_services — file sharing, screen sharing, remote login and the like, with the port — for nodes whose agent reports them. These are the host's own services, not published noBGP services. Details
  • Each node's peers are given the list too, which is what lets their agents offer those services to local applications.
  • A node running this agent is what fills that list: it reports the services its own host announces — file sharing, screen sharing, remote login, RDP. sudo nobgp config --mdns-report-services=false reports none instead, and clears what it reported before. Details
  • A service that runs but that the host does not announce is reported too — remote login on a headless Linux machine, remote desktop or file sharing on Windows. The machine's own listening ports are read; nothing is connected to. On Windows, file sharing is reported only when the machine shares a folder of its own.

Peers and their shares can appear in Finder​

  • sudo nobgp config --mdns-announce registers each peer as <name>-nobgp.local with this machine's own mDNS responder, together with the services that peer reports — so another node's file share turns up in Finder without typing an address. macOS and Linux, off until you turn it on, and nothing is announced on the LAN. Details

A node that has just registered starts on QUIC​

  • nobgp register now records the router's certificate pin, so a fresh node — a container registering with a key on every start included — connects over QUIC the first time instead of after a WebSocket connection. nobgp status reads quic_pin: learned straight away.

A refusal from a node says which node​

  • An error a node wrote now carries that node's name in front of it. A node names itself by its hostname, which is not how you addressed it and which two nodes can share. Details
  • A fan-out now counts refusals by reason, so a sweep says twelve nodes vetoed this without reading every event. command_subscribe with admin: "false" also counts, before anything runs, the nodes that have no unelevated identity. Details

A PowerShell script can call another script​

  • A script sent with shell: "powershell" now runs with the execution policy bypassed for that process, so a .ps1 file it calls runs too. Group Policy still wins. Details

You can be emailed before a machine reaches its time limit​

  • Turn on Email me before a machine reaches its time limit on your account page. noBGP then emails you before each of your machines stops, and again when it stops. It is off until you turn it on. Details
  • You choose how much warning: 15 minutes, 30 minutes, 1 hour or 2 hours. The choice is yours alone, so two people watching the same machine are each warned at their own time.
  • The app shows Stops in 41m above the machine, with Give more time beside it. This shows whether or not the email is on, and it uses the same warning time.
  • Move the deadline and the warning arms again for the new time. Extending a machine does not cost you the next warning.
  • The email goes to the person who provisioned the machine. If that person has left the organization, it goes to the organization Owners who turned the setting on.
  • A machine that reached its limit reads Stopped at its time limit in the app, so you can tell it from one you stopped yourself.

A Free machine can be given up to seven days​

  • The longest deadline you can ask for now comes from your plan: seven days on Free, no maximum on the paid plans. The refusal names the number of hours allowed. Details

The audit log says when noBGP stopped a machine​

  • A machine stopped at its deadline, at the included compute, on an empty balance or on a lapsed payment now writes its own entry, with the reason. Details
  • You can search the log by a node's name now, not only by id, and filter by any action the organization has actually used. Details
  • An entry names its target: a renamed node shows its current name on its old entries, and a deleted one still shows the name it had.

Your MCP client is told which scopes to ask for​

  • The sign-in discovery document and the 401 challenge now name the scopes, including offline_access — without it a client was issued no refresh token and its session ended at the first expiry. Details
  • A token noBGP cannot check because the sign-in service is unreachable now answers 503 with Retry-After instead of 401, so a client retries rather than sending you through sign-in again. Details

A machine keeps its name when it comes back​

  • noBGP now asks the agent itself whether a node is answering before it decides a name is contested. A machine restarting after a power cut, a kill -9 or a hard container stop is recognised as itself and keeps its node ID, labels, grants and storage area, instead of enrolling under a suffixed name with an empty storage area.
  • A node on a high-latency link — satellite, a congested mobile connection — is no longer read as gone when one packet is lost. It keeps its name the same way.
  • A node that is asked and does not answer is marked offline at once, rather than when its connection times out. A machine that is genuinely gone is still decided in about two seconds, so registering a replacement is no slower.

An omitted admin runs at the identity the node offers​

  • On the tools that run something, omitting admin now runs the work unelevated on a node that has a configured account, and elevated on a node that offers only its elevated identity. The result's admin_used says which one ran. One call now covers a fleet whose nodes differ. Details
  • ⚠ An omitted admin can therefore elevate, and a caller who may not elevate is refused with forbidden on those nodes. Send admin: "false" when the work must not run as the superuser.
  • admin: "auto" is now refused with invalid_args. Omit admin, or send "true" or "false". Details
  • When a node refuses an unelevated call, the message now names admin: "true" — and, on a node where an omitted admin would run elevated, omitting admin. It no longer names admin: "auto". Details

The Windows install command carries the key again​

  • register_node returns a Windows command that installs with no prompt, so an unattended install works again. It no longer returns a separate registration_key field. Pass the command on as it comes.
  • ⚠ The command contains the key, so the shell it is pasted into keeps it, and Windows records it where process-creation auditing is on. Rotate the key after an install you would rather not have on that record.

A provisioned machine no longer describes its image on the machine​

  • /etc/nobgp-image and /usr/share/nobgp-image/packages.tsv are gone, and network_directory no longer reports task_image_name or task_image_version. Compute Nodes describes the image and lists its packages.
  • ⚠ If a script reads either file, ask the machine instead: cat /etc/os-release for the release, apt list --installed for the packages, nobgp version for the agent.
Router 0.4.152–0.4.156 · agent 0.4.127–0.4.128

0.4.126 — September 2026​

The Windows Firewall rule is named after the profile​

  • The agent's inbound rule is now noBGP-<profile>, for example noBGP-default. Before, it was named after the tunnel adapter (noBGP-nobgp0), whose number can change. Details
  • At the next agent start, the old rule is renamed and keeps your edits. ⚠ A rule with duplicates left by a crash, or a rule whose rename fails, is replaced by a new rule without your edits. Check the rule after the upgrade if you edited it.
  • nobgp remove now removes the rule of the profile it removes. nobgp uninstall removes every profile's rule and any device-named rule left by an earlier release.
  • If the agent cannot read the firewall rules, allow-overlay now leaves the rule as it is.

nobgp mcp install no longer overwrites another nobgp entry​

  • If a nobgp entry in your Claude configuration is not a local node's, for example the public server, install now stops and asks you to rename it, for example to nobgp-public. --yes does not skip this. Details
  • uninstall leaves that entry in place, and nobgp mcp status reports it as not registered.

Stopping a machine tells you whether its name starts it again​

  • task_stop now returns restartable_by_name (router 0.4.151). false means that provisioning the name does not bring this node back, and notes[] says why.

A command waiting on stdin is explained​

  • The command tool description now says that a command that reads stdin waits until the session ends, and how to redirect stdin on each platform. Details
Router 0.4.151 · agent 0.4.126

0.4.125 — September 2026​

A name in use no longer drops​

  • A name no longer drops while a connection uses it. The agent now renews the name in the background and keeps the address served. Details
  • If noBGP no longer knows the name, a running connection keeps running. Only new lookups stop.
  • If noBGP is slow or unreachable, nothing changes. The agent tries again later.

A LAN name nobody uses is forgotten in a day​

  • A name discovered on a member's LAN is now deleted about a day after the last confirmation (router 0.4.150). Before, it stayed for a week. A name in use is not affected.
  • The member that holds the name is told that it is gone. The next lookup discovers it again if a member can still reach the device.
  • ⚠ Upgrade every member that is below agent 0.4.125. On an older agent, a busy name can drop once a day.
Router 0.4.150 · agent 0.4.125

0.4.124 — September 2026​

A Windows machine can keep its own firewall policy​

  • Set windows-firewall: respect-windows, or run sudo nobgp config --windows-firewall respect-windows. The agent then installs no inbound firewall rule and removes the old one. Details
  • The default is allow-overlay, so an upgrade changes nothing. The command tool, the file tools and published services work without the rule. Without it, another machine cannot connect directly to a port on this host over the overlay.
  • The rule is now created once and kept, so your edits to it stay. nobgp uninstall removes it.
  • You cannot set this with node_config_set.

The install script completes registration on RHEL-family hosts​

  • The install script now completes registration on RHEL, Rocky Linux, AlmaLinux, Oracle Linux and CentOS Stream. sudo nobgp … also works by name there now.
  • ⚠ If the script stopped part way on a machine, run sudo /usr/local/bin/nobgp register. See the troubleshooting entry.

A provisioned machine says which image it started from​

  • /etc/nobgp-image names the image and its version. /usr/share/nobgp-image/packages.tsv lists its packages. The image version is not the agent version. Details
  • The image now includes common network tools: ping, ip, dig, ps, an SSH client and more.

You can now stop a machine and keep its node​

  • task_stop stops a provisioned machine and keeps its node, name, labels, grants and node storage area (router 0.4.149). ⚠ The machine's local disk is destroyed. In the web app it is Stop. Details
  • Provision the same name again to start a new machine on that node. Stopping a stopped machine returns already_stopped: true.

More included compute on every plan​

  • From 15 September 2026, included compute goes up: Free from $0.50 to $1 a month, Pro from $1 to $5, Business from $20 to $50. Plan prices and rates do not change. Details
  • ⚠ The allowance is an amount of money, not hours. $5 is 250 small hours or 83 medium hours.
  • The launch promotion compute goes from $5 to $10.

A node answers to its own hostname​

  • You can now reach a node by its hostname, for example nas, even when its noBGP name is different (router 0.4.149). Details
  • A hostname that two of your nodes share answers for neither. A node stops answering its hostname about an hour after it goes offline.

Smaller things​

  • provision_node now takes network_id as well as network_name. Send one, not both.
  • The register_node one-liner no longer uses sudo. Run it as given. ⚠ Before, the sudo form wrote the full registration key to the system log of each machine installed with it.
Router 0.4.149 · agent 0.4.124

0.4.123 — September 2026​

Traffic no longer goes to a LAN device that moved​

  • When a member refuses a LAN name it can no longer reach, it now stops delivery at once. Before, traffic could go on to the old address, which may belong to a different machine.
  • The name keeps its overlay address. Delivery comes back at the next sync that resolves it. The member writes a log line, which you can read with node_logs.
  • Known issue: nobgp status still shows the old LAN address for such a name.

A command with lost output no longer reports success​

  • A command session that lost output no longer reports an exit code. The next poll returns resource_exhausted. Sending input to it is refused the same way.
  • ⚠ How much output was lost is not known. Write the output to a file on the machine and read it with fs_read, or use command_subscribe. Details
Router 0.4.147–0.4.148 · agent 0.4.122–0.4.123

0.4.121 — September 2026​

Large files are copied and read in full​

  • fs_copy and fs_read no longer cut a file after the first 1 MiB and report success.
  • A copy that cannot complete now writes nothing. A read that overruns returns what it received and the offset to resume at. To resume, ask for base64.
  • ⚠ Before, a truncated file looked complete and its digest matched. Copy again any file over 1 MiB that matters.

Transfers and long commands​

  • A slow reader now pauses the sender. The transfer no longer disconnects.
  • Polling now keeps a command alive. A long, quiet command is no longer ended after one hour.
  • A poll now returns in time, so you always get the command_id.

GPU fields​

  • A Windows machine no longer reports "kind": "none". It now sends no gpu block, because it does not check for a GPU yet. A Windows node below 0.4.121 shows none until it upgrades and reconnects.
  • unified is now absent when the machine could not check. false now means the accelerator has its own memory.

Node identity and cleanup​

  • An unclean reset no longer empties the token file and de-registers the machine.
  • Temp files left by a crash, including the private key and token, are now removed by nobgp remove, by uninstall and at agent start.
  • A refused copy or a lost cancel no longer leaves temp files or open files on the destination.

Other fixes​

  • On macOS, bare LAN names resolve again while the agent runs.
  • The local MCP event resource delivers events again. events is now always a list.
  • event_tail now accepts wait as well as wait_seconds.
  • A KVM now publishes the attached machine under the hostname from its DHCP request. --name is repeatable, and --no-lease-name publishes only your names.
  • Write tools now state that a write to a router-served tree replaces the whole file. Send the file in one call.
  • redact now covers every place the router could write command text.
Router 0.4.146 · agent 0.4.121

0.4.120 — September 2026​

You can now see how big each machine is in the network directory.

What a node reports​

  • cpu_count (logical CPUs), total_memory (RAM in bytes) and disk_free_bytes (free space where the agent runs). On a container, CPU and memory are the host's figures.
  • A gpu block with the interface (cuda, rocm, metal, rknpu or none), the device count, memory_bytes and unified.
  • ⚠ none means the machine found no accelerator. No gpu block means the machine did not answer. Do not read a missing block as "no GPU".
  • When unified is true, the capacity for a large job is total_memory. Otherwise memory_bytes is the card's own memory. rocm and rknpu nodes report no memory figure. An Intel Mac reports none.
  • A node reports a GPU device that it can see, even if the agent's account is not allowed to open it. Let the job prove access.

Provisioned machines keep to the size you bought​

  • A provisioned task now has a memory limit and a CPU share for its size.
  • ⚠ A task that uses more memory than its size is now stopped. Choose the size you need.

Commands to many machines accept more​

  • workdir and environment variable values now accept ", %, carriage return and line feed. A variable name with = or a null byte is still refused, and so are the variables that load a library into another program.

Other fixes​

  • A normal terminal session end on Linux no longer logs an ERROR.
  • A failed file-worker start no longer leaves a dead process.
  • Send expected_sha256 only on a chunked upload, not on a single-call write.
Router 0.4.144–0.4.145 · agent 0.4.120

0.4.118 — September 2026​

You can reach a device that one Linux member sees on its LAN​

  • Traffic now reaches a device that a Linux member vouches for on its own LAN, such as a printer or NAS. You configure nothing on the member. Details
  • Known issue: a member that runs macOS or Windows cannot carry this traffic yet.

A LAN name survives a reboot of its member​

  • A LAN name no longer stops working after the member that serves it restarts. The member resolves its names again when it starts.
  • If a name no longer answers, the member keeps its address reserved and writes a log line. Read it with nobgp service logs or node_logs.
  • A member that was up for more than a week no longer loses these names at restart.

Other fixes​

  • A LAN name that answers only over IPv6 is now refused, with the remedy: publish the device by IPv4 address, or give the name an A record.
  • One bad packet no longer takes down a node's overlay. The agent drops it and logs it.
  • A node now logs which directory entries it could not register.
agent 0.4.118

0.4.117 — September 2026​

An update no longer fails because /tmp is full​

  • If the temporary directory has no room, the agent now downloads the update to its configuration directory, when that directory has more room. Details
  • ⚠ A node that is stuck now needs its /tmp freed once, or a reinstall from the install script. After that, it upgrades on its own.

Saving refill settings again waits before it charges again​

  • After a save tries a charge, the next save waits about five minutes before it tries again (router 0.4.140). Details

A name on your network now means one thing​

  • A device found on a member's LAN can no longer share a name with one of your nodes (router 0.4.141). The node's name wins. Details
  • The week-long wait from 0.4.116 is over. When you rename or delete a node, its name can be discovered on a LAN again.

Tool descriptions​

  • admin goes inside session on command, inside source and destination on fs_copy and on file with op: "copy", and at the top level everywhere else. Details
  • Set a command's idle_timeout to the total wait you accept, not to the gap between lines.
Router 0.4.139–0.4.143 · agent 0.4.117

0.4.116 — September 2026​

Usage past your plan is now paid from credit and never invoiced. noBGP's own traffic no longer counts as yours. A LAN name stays on the machine that found it.

A discovered LAN name reaches only the machine that found it​

  • A name that one node resolves on its own LAN is no longer pushed to every node in the network. Other machines resolve their own bare names again.
  • On the machine that found the name, the name now resolves to the device, not to the machine itself.
  • The name is not broadcast any more, but a machine that asks for it still gets it.
  • Your agent now asks its own LAN first. If this machine can resolve a bare name itself, the overlay steps aside. See A name this machine reaches itself. nobgp resolve still prints the overlay address.
  • ⚠ Reaching the device through another member still times out in this release. Use the name on the machine whose own network sees the device. See A name one member reaches on its own LAN.
  • A machine can keep a stale entry for about a week. A restart does not remove it. A fresh install removes it at once.

Platform traffic is not metered​

  • Keepalives, the metrics push, token refreshes and subscription pushes are no longer measured. An idle node can now show zero traffic, as the pricing page says.
  • ⚠ The control_receive and control_transmit figures are removed from the usage breakdown. A client that reads the usage API by axis name no longer receives them. Older periods are not changed.

An old period's traffic reads its real bytes​

  • The bill, the usage bar, the ring and the chart now read the same record. A period older than about four months no longer shows 0 B and $0.00. The current period was never affected.

The card you last chose is charged​

  • A card that you change in the billing portal is now the card that is charged. A completed checkout also sets it. See Payment method.

A warning before your credit balance empties​

  • You now get the 80% and 100% allowance alerts before your credit balance empties and when it does. Each names the axis that runs out.
  • If you hold credit, the alerts now measure your included amount plus what your balance buys. See the restriction basis.
  • The 100% alert matches the condition that refuses creation. See When credit runs out.
  • An account with no spend cap is no longer told that it reached one.

A failed automatic refill tells you​

  • A new mail tells the account owner when the card refuses an automatic refill. Only a real card refusal sends it.
  • A declined refill now backs off. It no longer retries every fifteen minutes.

The smallest automatic refill is $5​

  • An automatic-refill rule below $5 is refused when you save it. A truncated refill does not buy less than $5.
  • A one-off credit purchase keeps the 50¢ minimum. An existing rule below $5 keeps its amount.
  • ⚠ An armed rule cannot buy when your maximum has less than $5 of room, and the default is $0. If you arm automatic refills, raise your maximum too.

Raising your spend cap buys the refill at once​

  • When you save a higher maximum or arm a rule, the refill is now tried at once. A slowdown now lifts in about eight minutes, not twenty-three.

New nodes are accepted at the start of the month​

  • At midnight UTC on the 1st, paid organizations are no longer refused with credit_empty for up to five minutes.

Usage is paid from credit, not invoiced​

  • ⚠ noBGP no longer invoices usage. Usage past your included amounts is drawn from your credit balance at your plan's rate. Rates and included amounts do not change. Enterprise is still invoiced against its contract.
  • Your spend cap now only limits automatic refills. An empty balance is what refuses, stops and slows.
  • A draw from credit is exact. Traffic is no longer rounded up to the whole gigabyte.
  • set_spend_cap and credit describe this. Do not build on credit_billed. It always reads true and will be removed.
  • A crafted sign-in link can no longer put your tokens in a published service's address. Other hosts get a cookie sign-in only.

A node logs its control-channel transport​

  • One info line now names the transport that carries the control channel and its address. The losing connection logs its close. See Log levels.

Smaller changes​

  • Checking out with a new card makes it your default.
  • A mid-period plan change is invoiced at once.
  • Switching from annual to monthly re-anchors your billing to the 1st.
  • A cancellation now always writes its audit log entry. ⚠ Earlier cancellations have no entry. Ask support if you need one.
  • Billing audit entries now include the amount. billing.credit_buy includes it on a refused charge too. Older entries are not backfilled.
  • The your subscription is active again mail now arrives after a recovered payment.
  • If your included allowance rises mid-period, the credit it covers comes back and spent_this_period_cents falls. Expired credit stays spent.
Router 0.4.130–0.4.138 · agent 0.4.116

Agent 0.4.114 — September 2026​

At the default log level, a node now logs only about itself.

  • An idle node no longer logs peer registrations, peer lifecycle, per-flow and per-ping lines, or the DNS re-arm probe at info. These are now debug. A NAS can let its drives sleep again. See Log levels.
  • To see peer presence, use network_directory or presence_subscribe.
  • node_logs and nobgp service logs can show older lines on an idle node. The log is not broken.
  • On a busy directory-joined host, the unelevated account check no longer reports that the node has no usable account.

Agent 0.4.113 — September 2026​

  • You can now set the address family that a node's connections try first: transport-family: auto | v4 | v6, --transport-family or NOBGP_TRANSPORT_FAMILY. See Address family.
  • auto is the default and does not change behavior. v4 and v6 try one family, then fall back to the other. Use this on a machine whose uplink breaks on IPv6. See when a machine's uplink breaks on IPv6.
  • You can set it remotely with node_config_set.
  • ⚠ The shared drive's transfers and the CLI's router calls do not follow it yet. On a host that must send no IPv6, also set fs: off or block IPv6 on the interface.
  • When the preferred family is dark, each connect waits a few seconds before it falls back.

Router 0.4.129 — September 2026​

You can change plan in the billing portal​

  • The billing portal now offers both Pro and Business, at both intervals. See Changing plan once you already have one.
  • Checkout is still refused while a subscription is live. A cancelled subscription can use checkout again.
  • Each plan card now shows its included traffic, rate, storage and compute hours from the plan catalogue.
  • A plan switch now removes the old plan's metered lines. Organizations on noBGP's own routers were never affected.
  • ⚠ A self-hosted deployment on its own Stripe account must configure its own portal.

Billing emails describe the spend cap correctly​

  • The cap mails now say that the spend cap only limits automatic refills. They offer two remedies: raise the maximum, or buy credit. See the emails.
  • The your subscription is active again mail now says only what a lapse withdrew.
  • Allowance mails now speak about their own axis only.

You can read usage per day​

  • Bandwidth and compute are now reported per UTC day, and the days add up to the period total. The usage screen draws the period from this. Old periods keep their chart.
  • Storage and nodes stay period figures.

Router 0.4.128 — September 2026​

macOS ._name sidecars are stored​

  • The share now stores a Mac's ._name files, so extended attributes, Finder tags and resource forks survive. See What travels with a file.
  • cp from a Mac no longer prints could not copy extended attributes and exits 1.
  • ⚠ A folder that a Mac wrote to now lists about twice the entries. .DS_Store, desktop.ini, Thumbs.db and autorun.inf are still discarded.
  • A sidecar follows the case rule.

An empty credit balance stops running machines​


Router 0.4.127 — September 2026​

Buying credit clears a creation refusal​

  • On a paid plan, creation is now refused only when an allowance is used up and the credit balance is empty. The error is resource_exhausted with limit_type: "credit_empty". See an empty balance is what refuses creation.
  • Under credit billing, the spend cap no longer refuses creation or stops running machines. A self-hosted deployment that invoices overage still refuses with limit_type: "spend_cap".
  • Agent enrollment refusals now say what is exhausted and how to clear it.

Your card charges leave a record​

  • credit op=purchases lists this period's purchase attempts, failed ones included. Use period (YYYY-MM) for another month.
  • Stripe now emails a receipt for each credit purchase to the organization's first Owner. A missing receipt does not mean a failed purchase.
  • credit status shows pending_purchase_cents and oldest_pending_purchase_at. Do not add the pending figure to purchased_this_period_cents. It is already included.

Cancelling clears auto-reload and the spend cap​

  • ⚠ Cancelling now clears the auto-reload rule and the spend cap. A new subscription does not re-arm them. Set them again if you subscribe again.
  • The old values go to the audit log as billing.credit_auto_reload_cleared and billing.spend_cap_cleared. org_audit_list returns them.
  • A lapsed payment keeps both settings.

Smaller changes​


Router 0.4.125 — September 2026​

You can extend a running machine with task_deadline_set​

  • You can now give a running provisioned machine more time, or less, with the task_id from provision_node.
  • ⚠ max_hours counts from now, not from when the machine started. Omit it to reset to your plan's default. 0 removes the deadline, except on Free.
  • A shorter deadline does not stop the machine now. Use deprovision_node for that.
  • You can change only a running machine. Provisioning the name again while it runs takes the next free name and starts a second machine.
  • The tool is not available when provisioning is revoked.

The directory shows each machine's deadline​

  • network_directory now shows task_deadline_at per node. Do not cache a remaining time. The deadline can change.

Enterprise machines have a deadline​


Router 0.4.124 — September 2026​

  • Allowance warning emails now have their own switch. Turning off billing no longer silences them.

Router 0.4.123 — September 2026​

Credit purchases complete​

  • credit op=buy and automatic refills now complete. Failed attempts charged nothing, and their reservations are released.

Usage is paid from credit on noBGP's own routers​

  • credit_billed now reads true. Usage past your allowance is drawn from your credit balance. Your invoice is the flat plan fee.
  • ⚠ An empty balance now slows traffic, not the spend cap. Buy credit to clear it.
  • Free does not change. Its traffic stops past its allowance.

Router 0.4.122 — September 2026​

The spend cap limits automatic refills only​

  • The maximum no longer refuses credit op=buy by an Owner. The maximum only limits auto-reload.
  • An automatic refill that does not fit is now reduced to what is left.
  • auto_refilled_this_period_cents is new on credit status. Headroom is spend_cap_cents minus this field.

An auto-reload trigger of zero is refused​

  • ⚠ credit op=auto_reload now refuses a trigger of 0. To refill when the balance is empty, use 1 cent.
  • reload_cents must be at least 50 cents.

Agent 0.4.112 — September 2026​

  • A node that cannot pick an overlay address now starts without one. command, file, the shared drive and nobgp status keep working, so you can repair the machine remotely. Before, agent 0.4.111 exited and restarted again and again.
  • nobgp status now shows the reason under network.overlay. See nobgp status.
  • ⚠ To bring the node back onto the overlay, free space in 100.64.0.0/10 or pin overlay-cidr to a free /20, then restart the agent. What to check, and what to do.
  • If the agent cannot read the routing table, it no longer takes 100.64.0.0/20 by default. It keeps a pinned or previously recorded /20 with a warning, and reports the error under network.overlay.
  • A pinned overlay-cidr must still be a /20 inside 100.64.0.0/10 and must not overlap a carrier-grade NAT gateway's /20.

Agent 0.4.111 — September 2026​

  • On Linux the agent now reads every routing table when it picks its overlay /20, not only main. A node no longer takes a range that another VPN, such as Tailscale, already routes, so it no longer registers and then reaches no peer. See Overlay addressing.
  • On every platform, a route that claims the whole 100.64.0.0/10 is no longer ignored as the agent's own leftover route.
  • If another product claims only part of the range, the agent now picks a free /20 elsewhere.
  • If another product claims all of 100.64.0.0/10, the agent logs no free /20 slice available in 100.64.0.0/10 (host is fully claimed). Free space in the range to use the overlay. Pinning overlay-cidr does not override this. What to check, and what to do.
  • Carrier-grade NAT uplinks, such as Starlink, work as before.

Known issue: on 0.4.111 a fully claimed host stops at startup and keeps restarting. 0.4.112 starts it without an overlay.


Router 0.4.120 — September 2026​

You can now rename a node from your assistant​

  • node_rename changes a node's name and keeps its node_id, labels, grants, services, public URLs and storage. Give the new name in new_name. Owner or Admin only.
  • ⚠ Connected peers resolve the old name until they reconnect. See what is stale.
  • After a rename, the old name provisions a new machine with provision_node, and the new name brings this one back.

Deprovision, then provision the same name, works in one step​

  • deprovision_node now waits up to 35 seconds for the node to go offline. A re-provision no longer gets a suffixed name and an empty storage area.
  • Read node_offline on the response. If it is false, poll network_directory until the node is gone before you provision.
  • ⚠ The call can now take up to 35 seconds. A client with a shorter timeout loses the answer, but the node is still deprovisioned.
  • If the deprovision cannot record its result, the call now fails. Retry it.

Credit buys charge the method Stripe charges​

  • credit op=buy now uses the subscription's payment method, then the customer default, then the only attached method. The billing summary shows the same method, with its type and, for Link or a bank, an account.
  • If several methods are attached and none is the default, the purchase is refused. Set a default in Account → Billing.

Router 0.4.118 — September 2026​

  • credit status now has credit_billed. It tells you if this deployment spends the credit balance on overage. On noBGP's own routers it is false: overage is invoiced, and op=buy returns failed_precondition. See Usage credit.
  • The balance is spent only when both credit_billed and credit_enabled are true.
  • Every credit call now writes an audit entry that names the operation: billing.credit_status, billing.credit_buy, billing.credit_auto_reload or billing.credit_spending. A refused charge is also recorded.

Agent 0.4.110 — September 2026​

  • On macOS the agent no longer switches on the pf packet filter. Before, it could enable pf and leave it on.
  • ⚠ Upgrading does not turn pf off again. How to check, and how to turn it off.
  • An idle node no longer writes a metrics line every minute. ⚠ Log lines about peers still keep NAS drives awake; 0.4.114 stops those. Use --log-level debug to see the line, or read net_metrics.
  • You no longer need to lower log-level to stop these writes. See Log levels.

Router 0.4.117 — September 2026​

  • A provisioned machine now stops at a deadline. provision_node takes max_hours and returns deadline_at. If you omit max_hours, the machine stops after 24 hours on Free, Pro and Business. The maximum is 8760 (one year). See How long it runs.
  • On Pro and Business, max_hours: 0 runs one machine with no deadline. Free refuses it. Enterprise machines have no deadline.
  • At the deadline the machine becomes an offline node. It keeps its identity, labels, grants and storage, and loses its local disk. Provision the same name to start it again.
  • ⚠ Machines provisioned before this release have no deadline. They run until you deprovision them.
  • There is no idle timer. A machine runs until its deadline, also when it is idle.

Router 0.4.116 — September 2026​

  • sudo nobgp register now works on a node whose noBGP name differs from its hostname. noBGP matches the machine's key first, then its name. The node comes back as itself, with its labels, grants, services and storage. See nobgp register.
  • You no longer need --name as a workaround.
  • A key conflict now names the node that holds the key, instead of enrollment failed. See enrollment failed.

Router 0.4.115 — September 2026​

  • You can now set whether your organization spends its credit balance with credit op=spending. It is Owner only, on the REST surface. enabled is required. With enabled: false, noBGP keeps the balance and slows the organization at its allowance.
  • credit status now returns credit_enabled, spent_this_period_cents and period_end.
  • On noBGP's own routers, the balance is not spent today. Overage is invoiced. See The meters.
  • create_checkout no longer says that Business is not on sale. You could buy Business before, and you still can. See Plans.

Agent 0.4.108 — September 2026​


Router 0.4.114 — September 2026​

Published services no longer see noBGP session cookies​

  • A published service no longer receives the visitor's noBGP cookies. Its own cookies pass through.
  • A service can no longer set a noBGP cookie. A Domain= attribute is removed, so its cookies stay on its own hostname. This also stops 400 Request Header Or Cookie Too Large errors from other services.
  • ⚠ Script on a service's page can still set domain-wide cookies. See Cookie isolation.

You can now read your plan, card and invoices in one call​

  • billing is a new Owner-only read on the REST surface. Page invoices with invoice_limit and invoice_starting_after. See Your plan, your card and your invoices.
  • ⚠ Read cancel_at_period_end with the status. A cancelled subscription stays active until the period ends.
  • create_billing_portal takes an optional flow: payment_method_update, subscription_update or subscription_cancel.
  • Allowance and spend-cap emails now give the reset date. They go to the organization's Owners. See The alert is emailed too.

Agent 0.4.107 — August 2026​

  • When no network interface is usable at startup, the agent now waits and retries instead of exiting. It starts when a link appears. See Waiting for an interface at startup.
  • ⚠ While it waits, nobgp status lists the profile as unavailable. An interface: name that does not exist makes the agent wait indefinitely.

Agent 0.4.106 — August 2026​


Router 0.4.113 — August 2026​

A contested name costs the name, not the connection​

  • A second machine with the same name now connects under a suffixed name, such as web-1, instead of being refused. A revoked node is still refused. See A contested name costs the name, not the connection.
  • ⚠ The machine does not learn its new name. Check the directory for unexpected suffixes, and give machines distinct names.
  • provision_node also suffixes a contested name. Read readopted_node_id to see what was re-adopted.

Other changes​

  • node_logs now says how many lines your filters removed and which filters were active. See How much your filters removed.
  • A deleted peer now stops resolving on a node that was offline when it was deleted. See Peer targets.
  • A mid-month subscription includes the whole month's allowance the first time only. A later subscription is prorated, but never lowers the allowance you hold. Free is never prorated. See One billing day.
  • A node's traffic and storage now count for the organization that owns the node.
  • A node that cannot report its boot time no longer shows 1970. Its health reading uses the connection-based rule.

Agent 0.4.105 — August 2026​


Router 0.4.112 — August 2026​

A node now has three states: online, offline and deprovisioned.

A stopped machine is an ordinary offline node​

  • When the platform stops a provisioned machine, the node keeps its node_id, name, labels, role grants and storage area. To start it again, provision the same name.
  • suspended_at is removed from network_directory. Read online and offline_at instead.
  • An offline node is no longer deprovisioned after a timer. It stays until you remove it, within the plan's storage limit.

A gigabyte is 1,000,000,000 bytes​

  • All bandwidth and storage allowances and per-GB rates now use decimal units: 1 GB = 1,000,000,000 bytes, 1 TB = 1,000 GB. This matches the pricing page. Nothing was charged against the old figures.
  • Machine memory stays in GiB. For a short time, the web app usage screen can read about 7% low. Details.

Provisioning a name a live node holds gets you a suffix​

  • provision_node no longer refuses a name that is online or has an open provisioning task. It uses the next free name, <name>-1 to <name>-8.
  • ⚠ Read node_name in the response. It is the only place that shows the suffix. Details.
  • A revoked node's name is still refused.

Renaming a node needs Owner or Admin​

  • Only Owners and Admins can rename a node now. A refused rename returns 403. Registering, provisioning, deprovisioning, picking a release channel and removing a node stay at Member. Roles & Permissions.
  • info.health and the host block of net_metrics no longer disappear when a node reconnects. Only a reboot hides the sample, for about 90 seconds.

Router 0.4.111 — August 2026​

  • task_id in network_directory now stays on a provisioned node after you rename it. You can deprovision a renamed node.
  • Provisioning a name again is refused while a container still runs behind a renamed node.
  • An old deprovision task no longer removes the node that a newer container runs as.
  • ⚠ A node that you rename before its replacement connects shows its previous task id. Wait for ready before you rename, then read the directory again. Details.

Router 0.4.110 — August 2026​

Every account can provision​

  • Provisioning is generally available on every plan, with no allowlist. If you were refused before, try again. Provisioning Nodes.
  • Limits come only from included compute, the spend cap and a lapsed subscription. These return resource_exhausted.
  • forbidden now means provisioning was revoked for your account. You can still use deprovision_node.

net_metrics health belongs to the current session​

  • The host block no longer shows a sample from an earlier connection. It is absent for about a minute after a reboot or reconnect. net_metrics.

node_logs says all three things unreachable can mean​

  • unreachable now names each cause: the log mechanism's reach, your since bound, or a log file that the running agent does not write. Details.
  • The one-line summary now says the answer is incomplete on every page that has the field.

A node's identity is its key, not its name​

  • A reconnecting agent is matched on its key. If you edit node-name on the machine, it no longer renames the node or creates a second node. Node Identity.

Router 0.4.109 — August 2026​

Every subscription bills on the first of the month​

  • New subscriptions bill on the first. A mid-month start pays a prorated fee and gets a full month's allowance.
  • The spend cap now bounds the invoice. On an annual plan, the cap is still per month. One billing day.

A billing alert stops naming a limit that has moved​

  • Allowance and spend-cap alerts clear when you upgrade or raise a limit. A later real crossing now alerts you again. Allowance alerts.

network_directory health belongs to the current session​

  • An online node no longer shows a health sample from an earlier connection. It is absent for up to about 60 seconds after a reboot or reconnect. An offline node keeps its last sample. network_directory.

Two things worth knowing before you trust a log​

  • Known issue: A log file can come from an earlier agent process. Check source and path first. Details.
  • Known issue: A since bound uses the node's clock. On a machine with no real-time clock, read a boot with since omitted. Details.

feedback_submit is not only for unattended sessions​


Router 0.4.108 — August 2026​

  • network_directory now reports online_at, the start of the node's current connection. A value later than your action means the node came back.
  • ⚠ online_at is not a liveness flag. An offline node keeps the start of its last session. Read it with online.
  • To wait for a node you disrupt, subscribe to presence events first. network_directory.

Router 0.4.106 — August 2026​

No plan caps devices any more​

  • Free's 25-node cap is removed. Every plan has unlimited nodes. limit_type: "nodes" no longer occurs. Plan limits.

On Free, passing the bandwidth allowance stops the traffic​

  • A Free organization over its 50 GB now has data traffic stopped until the period rolls over or it upgrades. On a paid plan nothing is stopped: a reached spend cap or a lapsed payment still throttles to 1 Mbit/s per node. Details.
  • Nodes stay online. Listing, stat, mkdir, delete, rename and lock still work. Transfers, service traffic, new command sessions and file reads and writes stop.
  • Drive URLs and mounts return 402 Payment Required. Tools return resource_exhausted with limit_type: "bandwidth". file op=fetch_url still works.
  • ⚠ After an upgrade or period roll, traffic comes back within a few minutes, not at once.

Router 0.4.103 — August 2026​

Compute is metered, and every plan includes some​

  • Provisioned nodes bill by the minute. Included compute: 25 hours on Free, 50 on Pro, 1,000 on Business. A medium hour uses three hours, a large hour six. Provisioned compute.
  • New classes: large (2 vCPU / 4 GiB) at $0.12/hour and xlarge (4 vCPU / 8 GiB) at $0.24/hour.
  • Known issue: a large or xlarge request can be accepted and then fail to start.
  • Any member can read usage per class with compute_usage on the REST surface.

Reaching a limit suspends a machine, it never destroys one​

The spend cap starts at $0, and covers compute too​

  • An organization with no cap now has a $0 cap. The cap covers bandwidth and compute. Allowance alerts now include compute. The spend cap.

Control-channel traffic is no longer billed​

  • Keepalives, metrics pushes, token refreshes and subscription pushes are no longer billed as bandwidth. An idle node can now show zero traffic. The meters.

Plan changes​

  • Pro is $20/mo ($200/yr). Allowances do not change.
  • Business is $200/mo ($2,000/yr): 1 TB bandwidth then $0.10/GB, 1 TB storage, 1,000 compute hours, unlimited nodes. Plans.
  • An account can own at most three Free organizations. Details.

Router 0.4.102 — August 2026​

  • Networks and services are now unlimited on the Free plan, as on every plan. No action is necessary. Plan limits.

Router 0.4.101 — August 2026​

One meter: bandwidth​

  • Nodes and storage are no longer billed. They are plan limits. Bandwidth over the allowance costs $0.12 / GB on Pro.
  • Free: 50 GB bandwidth, 25 nodes, 10 GB storage. Pro $19/mo ($190/yr): 100 GB bandwidth, unlimited nodes, 100 GB storage. Plans.
  • The $99 Business plan is retired. Existing organizations on it keep it.
  • The storage cap now applies on paid plans too. Delete always works. At the storage cap.

provision_node is sized by class​

  • Use class: small (0.25 vCPU / 0.5 GiB) at $0.02/hour or medium (1 vCPU / 2 GiB) at $0.06/hour. The default is small. Compute classes.
  • ⚠ cpu and memory now return invalid_args. Send class instead. provision_node.

Router 0.4.99 — August 2026​

  • The audit log records entries again. On router 0.4.98 it recorded nothing.
  • ⚠ Entries for calls made on 0.4.98 cannot be recovered. No tool call failed because of this. Audit log.

Router 0.4.98 — August 2026​

  • The audit log now records calls that address a node: command, file and fs_*, node_logs, node_config_get / node_config_set, net_* and the subscribe tools. Failed and denied calls are recorded too.
  • The entry goes to the organization that owns the node. Arguments and command text are not recorded.
  • ⚠ The log now grows with activity. Each fs_read call adds one entry. Audit log.

Agent 0.4.104 — August 2026​

  • An expired, idle leased overlay address is now reserved, not released. Quiet connections keep working, and packets no longer go to the wrong machine. Overlay Addressing.
  • A jump in the machine's clock no longer makes addresses in use look idle.

Agent 0.4.103 — August 2026​

  • On firmware that keeps /var/log in RAM, the agent log now survives a reboot. The agent writes <config-dir>/nobgp.log, up to about 20 MiB. Linux only. Details.
  • node_logs now says when your since bound removed lines, and when the lines come from a file the running agent does not write.
  • A node with no usable non-root account now says so, instead of telling you to configure one. Details.
  • Known issue: This release releases an expired, idle leased overlay address. Upgrade to 0.4.104. Overlay Addressing.

Agent 0.4.102 — August 2026​

  • After a router deployment, nodes now reconnect at spread times (±25%), not all at once. Backoff, exit codes and router.control_reconnects do not change.

Agent 0.4.101 — August 2026​

  • On an overlay-root Buildroot appliance, the agent now starts at boot. The boot link goes to /etc/kvmd/user/scripts/S99nobgp.
  • ⚠ If 0.4.100 is installed on such a machine, run nobgp upgrade, then nobgp service restart. Details.

Agent 0.4.100 — August 2026​

  • On a packageless Linux with busybox init, nobgp service install now works and the agent starts at boot.
  • ⚠ If 0.4.99 left the service half-installed, run nobgp service start or nobgp service restart. Details.

Agent 0.4.99 — August 2026​

Packageless Linux images install​

  • The one-line installer now installs on a Buildroot image with no package manager. The binary goes to /usr/bin/nobgp, config to /etc/nobgp/. nobgp upgrade works.
  • On a read-only rootfs, set INSTALL_DIR to a writable path that survives a reboot.
  • No shared drive backend is installed.

A busybox-init box gets a service — but not in this release​

  • Known issue: The service install fails on busybox-init images. Use 0.4.100.

Windows: a webdav drive cannot read a file over ~47 MiB​

  • Known issue: Windows' WebDAV client refuses files over 50,000,000 bytes with Permission denied. The write succeeds, but that machine cannot read the file. Use winfsp, or raise FileSizeLimitInBytes and restart WebClient. Details.

Agent 0.4.98 — August 2026​

A node now remembers the key of each peer and warns you when that key changes.

  • A node records the public key of a peer the first time the two nodes talk. It checks every later session against that key. The check is on by default.
  • ⚠ The check finds a key that changes after the first contact. It does not find a key that was wrong from the first contact.
  • To confirm a fingerprint, compare it with registration.agent_key_id in nobgp status on the console of the peer.
  • The new nobgp peers command lists the pinned keys. Add --json for scripts. It also works when the agent is not running.
  • The new peer-key-pinning setting takes warn (the default: log at ERROR and continue), enforce (refuse the session) or off. A refusal stops one session. It never stops the control channel of the node.
  • ⚠ A rebuilt node gets a new key under the same node ID. With enforce, its peers refuse it until you accept the new key on each peer. Use enforce only on a fleet where you do not often rebuild nodes.
  • To accept a rebuilt peer, run nobgp peers --forget <node-id-or-name> on each node that talked to it. You do not need to restart. --forget-all resets all peers.
  • With warn, the node reports the mismatch on every session until you resolve it.
  • The pins are in a <profile>-peerkeys.json file beside the profile. If the agent cannot read the file, it keeps the pins that it has. If you delete the file, the pins are cleared.
  • ⚠ You cannot change peer-key-pinning with node_config_set. Set it on the machine with nobgp config --peer-key-pinning.

Agent 0.4.97 — August 2026​

This release completes the QUIC change and fixes Windows upgrades, mount status and a shared-drive setting.

A slow machine keeps its QUIC connection​

  • The QUIC idle timeout of a node is now 120 seconds, up from 60. A healthy connection no longer drops when a keepalive is a little late. Nodes on wss do not change.
  • On QUIC, router.connected in nobgp status can now take up to 120 seconds to show a silent outage.
  • On QUIC, the offline short-circuit of the shared drive now starts after about three minutes, not two.

Fixes​

  • ⚠ On Windows, an upgrade no longer makes nobgp fail with Access is denied for accounts that are not Administrator. The next upgrade repairs a machine that has this problem. See the troubleshooting entry.
  • info.mount_readable in network_directory now changes when a mount fails. The node checks it on every cycle, also while it retries the mount.
  • ⚠ webdav-proxy-owners cannot be enforced. A node with this key now refuses all callers to the shared-drive proxy and logs an ERROR. If you set this key on a node, clear it. ⚠ Local processes on the node can still reach the proxy.
  • When the install script runs itself again under sudo, it now writes to a temporary file and checks it first. The curl … | sudo sh form is not affected.

Router 0.4.97 — August 2026​

A node that is gone no longer shows as online, and QUIC connections get more margin.

A node that is gone no longer reads online​

  • A node that disconnected while its router restarted no longer shows online: true in network_directory. A sweep closes these records every hour.
  • For a record that the sweep closes, offline_at is the time of the sweep, not the time of the disconnect.
  • presence_subscribe sends no offline event for such a node. If you must not miss a departure, also check the directory.

A slow machine keeps its QUIC connection​

  • The QUIC idle timeout of the router is now 120 seconds, up from 60. It takes effect when the node runs agent 0.4.97. The router still finds a dead node within 90 seconds.
  • The router no longer sends its own QUIC keepalives. The 25-second keepalive of the agent does not change, so nodes behind CGNAT are not affected.

Agent 0.4.96 — August 2026​

Both known issues of the previous span are fixed.

nobgp status shows a lost router connection​

  • router.connected in nobgp status now changes to false when the node loses the router.
  • The new router.since field shows when the current state started. The new router.offline_for_secs field shows how long the link is down. Both fields are also in the local MCP status tool.
  • A silent link failure shows within 68 seconds on wss. On QUIC it shows within about 60 seconds, and within 120 seconds from agent 0.4.97.
  • While the link is down, router.transport and router.remote_addr show the last connection.

The shared drive fails fast when the node is offline​

  • After about two minutes offline, a shared-drive operation now fails at once. It no longer waits for a network timeout. The node retries the work when it reconnects. See a node that already knows it is offline.

Fixes​


Router 0.4.96 — August 2026​

Searches report what they did not search, and Windows copies over WebDAV work.

  • ⚠ fs_grep and fs_grep_subscribe now return unreadable_paths and unreadable[]. Each path has a reason: not_found, permission_denied (retry with admin: "true") or unreadable.
  • Trust a zero result only when skipped_files and unreadable_paths are both 0. A node below agent 0.4.96 always reports 0, so check its info.agent_version. See A zero is only a zero.

Tool descriptions warn about Windows script encoding​

  • fs_write, fs_edit and file write UTF-8 without a byte-order mark. Windows PowerShell and cmd.exe do not read such a script as UTF-8, so characters outside ASCII break.
  • ⚠ Keep a .ps1, .bat or .cmd script to ASCII. Or send it through command's script field with shell: "powershell".

Fixes​

  • A copy onto a Windows webdav drive no longer fails with 0x80070021. Copy-Item, cmd.exe copy and an Explorer drag now work. A lock on a directory is still refused with 423.

Agent 0.4.94 – 0.4.95 · Router 0.4.94 – 0.4.95 — August 2026​

The shared drive and the log tools now report errors correctly. Router 0.4.94 fixes the known issues of the span below.

The shared drive reports what the server refuses​

  • ⚠ A rename that the server refuses now fails, and the file stays where it was. The same applies to a new folder whose parent is gone.
  • A drive that cannot reach the server no longer shows folders as empty. A listing now waits for the connection.
  • A rename made while the node is offline, or while the file uploads, is kept. The node sends it in order when the connection returns.

Known issue: while offline, a listing or rename on the shared drive can block for up to a minute, and nobgp status can show a lost connection as healthy. Agent 0.4.96 fixes both.

Log searches end with a clear answer​

  • node_logs with a pattern that matches nothing now returns an empty result, not an error.
  • Each page now has a scanned count of the lines it examined.
  • When the log goes back no further, the search ends with success and an unreachable note. To read more, run nobgp service logs on the node.

The known issues of the previous span are fixed​

  • A strict client can now use the flat node reference on all 16 tools.
  • node_config_set now writes only operational keys. It refuses all other keys, including router, insecure, quic-cert-pin, encrypt and auto-upgrade.
  • Files in a renamed folder on a fuse mount can be read at once. node_logs paging always ends. A trailing slash in an NFS mount point no longer causes remounts. org_display_name() no longer answers a caller who is not a member.

Fixes​

  • An orderly restart no longer logs reading from TUN: file already closed as an error.

Agent 0.4.84 – 0.4.93 · Router 0.4.82 – 0.4.93 — August 2026​

The MCP tools get one result shape and six new tools, with many fixes for fleets, files and the shared drive.

Every tool result has one shape​

  • ⚠ Every result is now one envelope. call_id, op, done and duration_ms are on the outside, and the payload is under a key with the tool name. This breaks a client that reads fields at the top level. See The result envelope.
  • An MCP failure now carries code, message, call_id, retryable and details. An error names its node, for example target_unreachable with details.offline_at.
  • admin on the tools that run something is now a string: "true" or "false". Every result reports admin_used.
  • You can name the node with node_id, or network_name + node_name, at the top level of the arguments. Do not also send the nested form, or you get invalid_args.

New tools​

  • node_logs reads the agent log of a node. It takes lines, since, min_level, pattern and cursor.
  • service_check tells you if a service backend is up: reachable, unreachable or not_applicable.
  • fs_copy copies one file between two nodes in one call. Neither node needs a route to the other.
  • node_config_get and node_config_set read and write the settings of a node over its control channel. Each key returns live, restart_required or refused.
  • feedback_submit sends free-text feedback to the noBGP team, up to 50 per organization per day.

Commands on a node and on a fleet​

  • You can read command output again. Send next_output_offset back as output_offset. The newest 1 MiB is kept. idle_timeout is limited to 100 s.
  • command_subscribe takes script, shell, workdir and env, so one dispatch runs on Linux, macOS, Windows and OpenWrt.
  • A signal result now shows signal_delivered, signal_mechanism and signal_target. stderr is now separate from output.
  • Output from Windows with characters outside ASCII now comes back as UTF-8.
  • ⚠ On macOS, an admin: "true" call uses the PATH of root, which does not include /usr/local/bin. If you get exit 127, use the absolute path.

Files​

  • ⚠ The default max_bytes of fs_read is now 32 KiB, down from 256 KiB. Use truncated and next_offset to read the rest.
  • transfer: "url" gives a short-lived /xfer/ URL that a browser, CI or op=fetch_url can fetch. It works from router 0.4.87.
  • expected_sha256 is now checked on the shared drive and on node storage areas. A mismatch returns precondition_mismatch and does not change the file.
  • A failed write now removes the parent directories that it created.
  • fs_grep returns its matches again when you send a progressToken.
  • A recursive delete inside /tmp, /var/tmp or C:\Windows\Temp no longer needs force: true.

Watching a fleet​

  • fs_subscribe and presence_subscribe take keep_seconds, up to 24 hours.
  • presence_subscribe adds a ready event when a session holds for 5 s. Wait for ready after a provision.
  • A noBGP write shows in fs_subscribe as create, not write.
  • net_metrics now reports host.cpu_percent, mem_free_bytes, load1 and at. load1 is not available on Windows.
  • network_directory now shows info.fs_mount and info.mount_readable.

The shared drive​

  • When you rename a folder, its cached files move with it, and a queued save uses the new name.
  • nobgp status shows an fs.unreadable line when the agent cannot read its drive, with the remedy. On macOS it names the Full Disk Access grant.
  • A Mac that cannot mount after a change to fs: now repairs itself.
  • A refused write-back is kept and listed under fs.conflicts in nobgp status.
  • File locks now survive a router deploy.
  • A delete now answers at once. The names .nobgp-trash and .nobgp-upload-* are reserved.
  • The Free storage allowance is enforced: 507 Insufficient Storage on the drive, and resource_exhausted on fs_write, fs_mkdir and fs_copy. Deletes and moves are always allowed. This is off until enforcement is switched on.

Staying connected​

  • A sleeping laptop no longer counts as a flapping node, so its agent no longer restarts.
  • A dropped control connection reconnects without a restart. In nobgp status, router.quic_reconnects is now router.control_reconnects.
  • A node whose DNS fails stays reachable.
  • nobgp service restart now schedules the restart and returns. Exit 0 means that the restart is scheduled.
  • A change to fs in the config no longer reloads the agent. Restart the agent to apply it.
  • A deleted name leaves the directory of every node at once.

Billing and limits​

  • Per-call rate limits apply: 600 calls a minute with a burst of 120, per caller and per target node. A refusal is rate_limited with details.retry_after_ms.
  • The spend cap now limits only overage. A cap of 0 means no overage.
  • Allowance alerts at 80% and 100% now reach every plan, including Free.
  • Bandwidth throttling starts only when enforcement is on.
  • A personal organization shows the name or email of its owner instead of an ID.
  • MCP calls now appear in the audit log of the organization. The router no longer sends command text, stdin, output or caller emails to product analytics.

Smaller changes​

  • nobgp status adds fs.no_fallback, fs.locking, fs.conflicts and fs.unreadable. network_directory adds info.health and info.writable_roots.
  • /mcp and /api/v1 support gzip.
  • Provisioned node images run tini as PID 1, so a package install no longer hangs.
  • The router and the agent use Go 1.26.7.

Known issue: a code review found defects in this span, for example the flat node reference on 12 tools and the keys that node_config_set could write. Agent 0.4.94 and router 0.4.94 – 0.4.95 fix all of them.


Agent 0.4.83 — August 2026​

You can now restart a node remotely​

  • ⚠ nobgp service restart now schedules the restart outside its own process tree and returns about two seconds before the restart. Exit 0 means "scheduled", not "back up". Confirm with nobgp service status.
  • A restart from a noBGP command session no longer leaves the node down until someone reaches its console.
  • If the host cannot schedule the restart, the command tells you. In a noBGP command session it refuses and names a local console or a reboot. In a local shell it warns and restarts in place.

Nodes stay connected​

  • A node on WebSocket now reconnects inside the running process after a dropped control connection, as a QUIC node already did. It no longer exits and rebuilds its tunnel and shared drive.
  • nobgp status renames quic_reconnects to router.control_reconnects. Read it beside router.transport.

The shared drive​

  • nobgp status shows a new fs.no_fallback line on a host that can run only one filesystem backend. Where a fix exists, the line names it, for example installing WinFsp on a Windows node.
  • A busy answer that outlasts the retry budget now reports the status it saw, not context deadline exceeded.

Diagnostics​

  • net_interfaces now returns an overlay block: the tunnel interface, its slice, and the address the node's own name resolves to. It needs this agent release and router 0.4.81.
  • A name the router withdraws, for example a deprovisioned peer, now stops resolving at once. Its address stays reserved.

Fixes​

  • Installing a database server, for example mysql-server, on a provisioned node no longer hangs. A container provisioned before this keeps its old image. Provision the name again to move it to a current image.
  • An unelevated file operation no longer fails with fs worker is gone.

Router 0.4.81 — August 2026​

You can now send a whole script to a node​

  • command takes a script: a whole script body with real newlines and no escaping. Send command or script, never both. On Windows the body runs as a batch script, or as PowerShell with shell: "powershell", without the 8191-character line limit.
  • script is refused on a node that never reported its OS. Send command, or set shell: "powershell". A body over the platform limit (about 9 KiB batch, 12 KiB PowerShell, 117 KiB shell) is also refused. Write it with fs_write and run its path.
  • A Windows call that exits 255 with no output and no shell now returns a hint with the two ways through.

Diagnostics​

  • ⚠ net_interfaces now returns an overlay block with the node's TUN interface, its /20 slice, and the address its name resolves to on that node. The node must run agent 0.4.83. Do not use the interface's addrs for this.
  • The router now withdraws a deleted or deprovisioned node's name from the other nodes' directories. A node needs agent 0.4.83 to act on it.

Searching and moving files​

  • fs_grep_subscribe now takes admin, as fs_grep does. A node whose owner refuses elevation reports that as its own event, and the search continues.
  • A file transfer no longer breaks when a follow-up call reaches a different server. Listings, stats and other one-shot operations are not forwarded. If one names the owner, retry the call.

Agent 0.4.79 – 0.4.82 · Router 0.4.77 – 0.4.80 — August 2026​

Windows nodes change how they mount the drive. Read the first section if you run one.

Windows nodes now mount the drive with WinFsp​

  • ⚠ From agent 0.4.82, fs: auto selects WinFsp on Windows where the driver is present, instead of WebDAV. This happens without notice, also where rclone, sshfs-win, Cygwin or MSYS2 installed WinFsp. Set fs: webdav to keep WebDAV, or fs: off for no drive.
  • Renaming a file is slower on WinFsp than on WebDAV. Agent 0.4.82 should reduce the gap; it has not been measured again.
  • Renaming a file to a different capitalisation, for example report.txt to Report.txt, now works.

File locks on the shared drive​

  • An interrupted copy no longer makes a file unwritable. Copying a file such as an .msi in Explorer no longer fails with 0x80070021. From router 0.4.80, every lock expires after at most ten minutes.
  • From router 0.4.80, a lock applies across the whole service and is released when the node that holds it disconnects.
  • A drive LOCK and a file op=lock now contend on the same file. Locks stay advisory.
  • ⚠ From router 0.4.80, a lock on a whole folder is refused with 423. Lock the files you write instead.

What the drive does not carry​

  • ⚠ The drive does not carry the extra streams Windows attaches to a file. A file copied through it loses its mark-of-the-web without a prompt, so Windows treats it as locally created.

Deleting and mount health​

  • From router 0.4.77, a delete answers at once, and every server sees it at once.
  • From agent 0.4.82, an nfs mount that disappeared no longer reports healthy. The node mounts it again.
  • From agent 0.4.82, a refused write can no longer overwrite the winner's bytes. The conditional write holds.

Nodes that go quiet stay reachable​

  • From agent 0.4.80, a node whose DNS lookups fail stays reachable. It uses the address its connection last reached.
  • From router 0.4.79, a session that failed because the node could not reach the service is retried once.
  • From agent 0.4.82, an upgrade download that ran out of disk can start again.
  • From router 0.4.77, a write that was not delivered is no longer reported as delivered.

Writes are verified end to end​

  • A file written through the tools is now verified end to end, so a corrupted transfer fails. Send expected_sha256 to fs_write to also check the leg between you and the service.

Accounts and sign-in​

  • From router 0.4.78, a name that Google or SSO provides after sign-up fills an empty profile name at your next sign-in. An existing name is not overwritten.
  • After an email-code sign-in, the sign-in page prefills your address on your next visit.
  • A name of only spaces is no longer stored. An invitation with a stray tab no longer creates two grants.

For MCP clients​

  • From router 0.4.77, clients can cache the tool list.

Agent 0.4.56 – 0.4.78 · Router 0.4.57 – 0.4.76 — August 2026​

The shared drive now mounts in the way the machine supports. No action is needed beyond upgrading.

Your node picks how it mounts the drive​

  • The agent tests FUSE, NFSv4, WebDAV and WinFsp on the machine and uses one that works. nobgp status and nobgp show report the result.
  • New fs config key: auto | off | nfs | fuse | webdav | winfsp. auto is the default. The agent uses an explicit choice or refuses it, and never replaces it.
  • fs: off mounts nothing and logs why once.
  • nobgp show reports the fs selection, fs-backend and fs-error.

The drive is faster​

  • Listings and file bytes are cached for every backend. Repeat reads of an unchanged file are served locally.
  • ⚠ Set fs-cache-ttl (flag, NOBGP_FS_CACHE_TTL, or profile) with a unit, for example 30s. The default is 30s, the range 0–10 minutes. The agent ignores a value without a unit and keeps the default.
  • NFS writes on Linux now run at full speed.

Your data is safer​

  • Two nodes that create the same file at once no longer destroy one copy. The second writer fails, and its bytes stay on the node.
  • From router 0.4.76, a conditional write is checked again when the upload completes. A losing write gets 412.
  • A queued save now survives an agent restart, including an automatic upgrade.
  • An append now writes at the correct offset.
  • Names are stored exactly as written and are unique without regard to case, so case.txt and CASE.TXT cannot both exist.
  • Deleted or overwritten files are recoverable for 7 days. Contact support.

Errors on the drive are clearer​

  • From agent 0.4.77, a short busy answer (429, 502, 503, 504) is retried for up to 5 seconds and no longer shows as Input/output error. Details
  • From agent 0.4.78, a mount left by a killed agent is removed at startup, also on a node with fs: off. Linux and macOS only.
  • From agent 0.4.78, the agent no longer restarts when it writes its own profile file.
  • A busy mount point now names the process that holds it. The agent does not stop that process. A mount path that contains a space now works.
  • fs_locking in network_directory shows what file locks a mount guarantees.
  • macOS now mounts over NFS, where a lock that cannot work fails instead of reporting success.
  • ⚠ On macOS, the agent service cannot read the node's mount. Grant the nobgp daemon Full Disk Access on that Mac. Or address the storage through the router: a network's drive by network name, or the node's area with storage: true.
  • WebDAV needs davfs2, which some Linux distributions do not install and Synology does not offer. Without FUSE or NFS, such a node runs without the drive.

Windows​

  • WinFsp 1.10 or newer is available as an opt-in backend. Set fs: winfsp to use it.
  • Editing a file through the file tools now works on Windows.
  • Explorer now shows the drive as noBGP.

macOS​

  • Correction: WebDAV on a Mac works. See the numbers. nfs stays the default.
  • The macOS binaries are now signed with a Developer ID certificate, so a Full Disk Access grant survives an upgrade.

Storage and billing​

  • The usage screen now shows node storage per node, beside the per-network view.
  • A network deleted mid-period that was billed now shows on the usage screen.
  • A deprovisioned node's storage is released after 30 days.
  • network_directory shows which backend each node mounted with.

See Plans and billing and What the mount contains.

Nodes​

  • A network rename now reaches mounted nodes at once.
  • Provisioning a name that is in use now replaces the node that provisioning created. A node you registered by hand is still refused.
  • nobgp register now re-registers a node whose token expired.

Reliability​

  • A restarted agent no longer stops its node accepting sessions with destination recently closed.
  • fs_read now reads files larger than 1 MiB on the shared drive and a node's storage area. A partial page returns done: false. Continue from offset + size.

Agent 0.4.55 — August 2026​

Files that went missing from the mounted drive on macOS and Windows are back.

  • Listings under node/ and networks/<name>/ no longer lose entries on macOS and Windows, at any depth.
  • A network name that contains a space now lists correctly.

See What the mount contains.


Agent 0.4.54 — August 2026​

The mounted drive holds two folders now: the machine's own storage, and one per network.

  • ⚠ The mount root now has two folders: node/, this machine's own storage area, and networks/, one folder per network. A file at /mnt/nobgp/report.pdf is now at /mnt/nobgp/networks/production/report.pdf. Storage, URLs and the dashboard do not change.
  • node/ is the same path on every node and needs no URL or token. Reading it from elsewhere needs Owner or Admin.
  • The root and networks/ are read-only.
  • A move between the two trees is a copy. A program that only renames gets a "cross-device" error.
  • The layout is the same on Linux, macOS and Windows.

See What the mount contains.


Router 0.4.56 — August 2026​

Your assistant can read and write noBGP's own file storage, without going through a node.

  • file and the fs_* tools can now reach a network's shared drive (a network and no node) or a node's own storage area (storage: true with the node id). The node does not need to be online.
  • A network's share needs Member. A node's storage area needs Owner or Admin.
  • read, write, list, stat, mkdir and delete work on storage, up to 1 MiB per call. For a larger file, use the tree's HTTPS URL.
  • storage: true requires the node id, not its name.
  • ⚠ On storage, delete always removes the whole subtree, and admin is ignored.

See Addressing storage instead of a node.


Router 0.4.54 — August 2026​

The shared drive has a URL you can actually open.

  • You can now open a network's share at https://files.nobgp.com/networks/<network-id>/ with any WebDAV client and your noBGP bearer token.
  • files_url in network_directory now resolves to that URL.
  • Each node has its own storage area at https://files.nobgp.com/nodes/<node-id>/. It needs Owner or Admin in the organization that owns the node. ⚠ A write to it passes none of the vetoes the node's owner sets on the box. A node reaches only its own area.

See Reaching a share directly and the role matrix.


Agent 0.4.53 — August 2026​

The local proxy behind the shared drive can tell who is calling it.

  • The new webdav-proxy-owners key limits the local WebDAV proxy on 127.0.0.1:19840 to a list of numeric uids. The empty default only logs the uid of the first caller. Linux and macOS only.

⚠ Correction, agent 0.4.97: this key cannot work on any platform, and the logged uid is not the caller's. Leave the key unset. If you set it, the drive goes offline.

See Shared drive proxy keys.


Router 0.4.53 — August 2026​

The shared drive is now a real filesystem, and file names are case-sensitive because of it.

  • ⚠ README.md and readme.md are now different names. A request with the wrong case returns 404. Router 0.4.71 later made names unique without regard to case.
  • An upload that stops part way no longer replaces the file, when the client declares the length.
  • A file rewritten within one second is no longer served stale.
  • A lock in one network no longer blocks the same path in another network.

Agent 0.4.52 — August 2026​

Turning off a node's last way in now takes a deliberate answer, and stopping the service is bounded.

Node settings​

  • ⚠ Removing command from allow-tools now asks for confirmation. A non-interactive run, including nobgp config over MCP, is refused unless you pass --yes. Undoing the change needs console, RDP or SSH access.
  • --yes answers these prompts for one run. It is not saved.
  • To clear the configured account, run sudo nobgp config --user "". On a node whose agent is the superuser, admin: false calls are then refused (unelevated never means root). A reinstall or registration sets the account again.
  • The allow-admin: false warning now states which effect it has on this node. See Confirmed before it is written.

Stopping the agent​

  • Stopping the service now takes at most seventeen seconds on Linux, macOS and Windows, however many profiles run. One stuck agent no longer holds up the others.
  • Every unmount on Linux and macOS now stops after five seconds per attempt and escalates.

Agent 0.4.51 — August 2026​

The shared drive now mounts on Linux nodes that had no FUSE helper.

  • The .deb, .rpm, .apk and .ipk packages now declare the FUSE helper (fuse3, or fuse-utils on OpenWrt). On RPM hosts it is a recommendation, so an EL7-class host still installs and runs without a shared drive.
  • On OpenWrt, install.sh now installs kmod-fuse and fuse-utils.
  • If the helper is missing, the agent now logs one error that names the package to install. It no longer repeats a warning every minute.
  • ⚠ Before, /mnt/nobgp could stay empty. On an affected node, install the helper and restart the agent:
opkg install kmod-fuse fuse-utils # OpenWrt; elsewhere install fuse3
sudo nobgp service restart

Router 0.4.50 — August 2026​

  • network_directory now reports offline_at for each node that is down. It is the time of the most recent disconnection, in RFC3339 UTC.
  • The field is absent when the node is connected, has never connected, or has no recorded disconnection. Absent does not mean "long ago".
  • offline_at is also returned with brief: true. You do not need to upgrade any agent.

Agent 0.4.50 — August 2026​

  • The agent now checks the router's QUIC certificate pin on every connect, including a resumed session. After a certificate rotation, the node re-pins on the next connect and does not fall back to WebSocket.
  • You do not need to configure anything. quic_pin in nobgp status is unchanged.

Router 0.4.49 — August 2026​

  • The MCP endpoint's metadata now names one authorization server, noBGP's sign-in service. An MCP client that chose the second entry can now sign in.
  • The router no longer serves authorization-server metadata of its own. Clients that already sign in, such as Claude Desktop and Claude Code, are unaffected. If you write your own client, see the discovery contract.

Agent 0.4.49 — August 2026​

  • The agent no longer exits when the network is briefly absent after a wake from sleep. It retries in place for up to five minutes, on Windows too. Stale nobgp volumes on macOS no longer result from these exits.
  • A revoked node or a refused connection still stops the agent at once.
  • Peer sessions now come back at once after a reconnect that needed a retry.

Agent 0.4.48 — August 2026​

The filesystem mount survives a network blip​

  • A mount is no longer remounted after one failed health probe. It must fail three probes in a row, about one minute. Duplicate nobgp drives no longer appear in Finder.
  • An orderly stop no longer delays the next mount by ten minutes.
  • On macOS, the agent now gives the unmount 15 seconds to finish at shutdown.

Other changes​

  • A node that cannot switch to its configured account now returns failed_precondition (HTTP 403, not retryable). Before, it returned a retryable internal. Retry with admin: true.
  • An auto-upgrade on slow hardware no longer logs auto-upgrade failed after it succeeds.

Agent 0.4.47 — August 2026​

  • A node now reports a permission denial as permission_denied (HTTP 403, not retryable) on Linux, macOS and Windows, in any system language. Before, it could arrive as a retryable internal.
  • The result is the same at both identities. What a node permits did not change.

Router 0.4.48 — August 2026​

  • An ACL denial on a Windows node now returns permission_denied (HTTP 403, not retryable), as on Linux. Before, it returned a retryable internal.
  • The router matches the English message. On a Windows node in another language, upgrade the agent to 0.4.47.

Agent 0.4.46 — August 2026​

A Windows node runs everything as its configured account​

  • On a Windows node with a configured user, command, terminal sessions and bus commands now run as that account with admin: false. They no longer refuse. See A second identity on Windows.
  • allow-admin: false on such a node now narrows it to that account instead of switching it off.
  • The first unelevated command for an account creates its profile folder, and nobgp uninstall keeps it. That account has no network credentials, so a command that reads a file share needs admin: true.

Security​

  • ⚠ On 0.4.44 and 0.4.45, on a Windows node whose user was an administrator, an unelevated fs_read could read files that the account had no permission to read. This no longer happens. Other nodes were not affected.

Other changes​

  • network_directory now shows whether the unelevated account is an administrator (info.user_is_admin, router 0.4.47). nobgp status shows unelevated_is_admin. Absent is not false.
  • A terminal session on Windows older than 10 1809 now returns an error instead of crashing the agent.
  • A Linux node no longer runs out of overlay interfaces because of stuck subprocesses.
  • A stuck filesystem mount no longer blocks startup.

Router 0.4.47 — August 2026​

  • network_directory now returns info.user_is_admin. When it is true, admin: false runs as an administrator on that node. It has three states, and absent is not false.
  • The admin guidance no longer says that Windows nodes have no unelevated identity. A Windows node has one only where its owner configured an account.

Router 0.4.46 — August 2026​

  • When you omit network_name, the call now uses your personal network, even if you belong to team organizations. The call asks you to choose only when you have two personal networks, or none.
  • To use a shared organization's network, name it. This applies to command, file, fs_*, the selector fields, provision_node, register_node and network_delete.
  • A network_id now always selects that exact network. Before, it could select your personal network with the same name.

See Which network a call lands in.


Agent 0.4.45 — August 2026​

  • network_directory now shows the machine model as info.hardware_model, for example DS918+ or Macmini9,1. It can be empty on a VM, a container or an older agent.
  • fs_write, file op=write and op=fetch_url now create missing parent folders. You no longer need fs_mkdir first.
  • The new folders belong to the identity that admin selects. allow-roots still applies.

Agent 0.4.44 — August 2026​

Execution identity​

  • A configured user now gives a Windows node its second identity. The windows-user-identity key is retired, and the upgrade removes it. See A second identity on Windows.
  • A Windows node that recorded an install account now runs unelevated file calls as that account. command and terminal sessions still refuse an unelevated call.
  • nobgp config --user <account> now works on Windows. network_directory shows the account.

Provisioning​

  • A provisioned node now accepts admin: false from its first boot.
  • NOBGP_USER now also works on an installed agent, and overrides the config file. See Environment Variables. nobgp config --user tells you when NOBGP_USER overrides the value you saved.

Installing and upgrading​

  • The Windows installer no longer reports a registered node as failed. It names the command that fixes the service.
  • Re-running the installer over a running agent no longer reports a failed install.
  • Errors print once, and flag mistakes now print a message.

Router 0.4.45 — August 2026​

Provisioning​

  • provision_node now tells you how to wait for the new node, and returns network_name and the normalized node_name. It still returns no node_id.
  • resource_summary now shows the CPU and memory actually allocated.
  • deprovision_node now succeeds on a task that is already stopped.

Directory and services​

  • A filtered network_directory no longer returns networks with no matching node. A network you name with network_name is still returned.
  • Brace expansion in a glob, such as {web,db}*, now returns invalid_args instead of zero nodes.
  • service_publish now tells you how to check that the backend is alive.

Stale tool lists​

  • A boolean sent as a string ("true", "false", "1", "0") is now accepted.
  • A validation error now tells you to refetch the tool list and names the router version. See When your client's tool list is stale.

Agent 0.4.43 — August 2026​

  • A Windows node can now run fs_* and file calls with admin: false as a configured account. Set windows-user-identity: true and a user. No password is stored. The key is off by default. See A second identity on Windows.
  • On such a node, an unelevated command or terminal session returns failed_precondition. Send admin: true.
  • nobgp config --user <account> works on Windows when the key is on. A Windows install records the signed-in desktop account in user.
  • network_directory shows that account when the key is on.
  • A node that fails during startup now records the reason when it closes its connection.

Agent 0.4.42 — August 2026​


Router 0.4.43 — August 2026​

  • whoami now returns can_elevate. When it is false, every admin: true call returns forbidden. A node with allow-admin: false still refuses. See two gates.
  • whoami also returns orgs[], with your role and can_elevate for each organization. If your roles differ, there is no top-level can_elevate.
  • network_directory now returns org_id on each network, to match orgs[].
  • Send admin: true for work that needs the superuser, and omit it otherwise. See Choosing which to send.

Agent 0.4.41 — August 2026​

  • A node now refuses admin: false when that call would run as root (uid 0). This includes a service install with no user, a bare-root container, every Windows node, a deleted user, and user: root. The refusal is failed_precondition. See Unelevated never means root.
  • ⚠ To serve unelevated calls, run sudo nobgp config --user <account>, or send admin: true.
  • An agent that already runs unprivileged still serves admin: false.
  • nobgp config --user root is now refused. --allow-admin=false now reports the node's actual case.
  • network_directory info.user is now empty when the configured account does not resolve.

Router 0.4.42 — August 2026​

  • The router now returns a node's refusal of admin: false as uid 0 as failed_precondition (not retryable). To fix it, configure an account (sudo nobgp config --user deploy) or retry with admin: true. See Unelevated never means root and the tool descriptions.
  • Each node enforces the rule when its agent upgrades. Privilege does not change: root work now needs an explicit admin: true.
  • network_directory info.user now has three states: a name, empty (no account), and absent (the agent does not report it).

Agent 0.4.40 — August 2026​

  • A node now refuses a one-shot answer over 64 MiB with too_large. This can affect a recursive fs_list or a very large fs_glob. Narrow path or drop recursive, because limit and offset do not help.
  • A large answer no longer uses twice its size in memory.
  • A search now reports files skipped for size. See A zero is only a zero when skipped_files is 0.

Router 0.4.41 — August 2026​

  • fs_grep now returns skipped_files, the count of files over the 16 MiB limit that it did not read. fs_grep_subscribe reports it in each completion event.
  • ⚠ Check skipped_files before you trust a zero. An agent below 0.4.40 always reports 0.

Router 0.4.40 — August 2026​

Organization roles now apply to the tools that write a node or a service. Solo accounts and personal organizations do not change.

  • The Member role is now checked on service_publish, service_update, service_delete, service_share, register_node, provision_node, deprovision_node and node_label. A Member keeps all operational actions: nodes, services, command and the file tools. See Roles & Permissions.
  • ⚠ Only an Owner or Admin can now turn off a service's authentication (auth_required: false) on service_publish or service_update, or run node_label. A Member gets forbidden (HTTP 403). If a Member does either step as routine, raise their role or move the step to an Owner or Admin.
  • Turning authentication on, editing a service that is already public, and passing authorized_emails need no extra role.

Agent 0.4.39 — August 2026​

  • File walks (fs_list, fs_glob, fs_grep, fs_stat and the file ops) now report results under the path you sent, not under the resolved symlink target. fs_stat of a link describes the link again.
  • A walk now starts at the same path that the allow-roots check approved.
  • Windows: a finished stderr line no longer waits behind an unfinished one. Prompts and progress lines now show at once.

Router 0.4.38 — August 2026​

  • An fs_grep or fs_grep_subscribe pattern that is not valid RE2 now returns invalid_args (HTTP 400). Before, it returned a retryable internal.
  • Text you send, such as a pattern or a file name, is no longer read as a node refusal. It no longer causes a false permission_denied, not_found or too_large. See When the failure came from the node.

Agent 0.4.38 — August 2026​

File tools​

  • One large reply no longer breaks later file calls on a node until a restart. Large replies are now sent in parts.
  • The same size limit now applies with and without admin: true. Going over it returns too_large, not internal.
  • macOS: a recursive walk of /tmp, /etc or /var now finds the files. Before, it returned an empty success.
  • An operation now acts on the path that its permission check approved.

Errors and commands​

  • A node now sends its own error code for a refusal. An unknown refusal no longer arrives as a retryable internal.
  • A command stopped by a signal now reports 128 + the signal number, for example 143 for SIGTERM. Windows still reports 1.
  • Windows: quotes now reach cmd.exe unchanged, as at a Command Prompt.
  • Windows: shell: "powershell" output is now plain text, without CLIXML. Error text is kept.

Router 0.4.37 — August 2026​

  • A node owner's refusal now returns permission_denied (HTTP 403, not retryable), not a retryable internal. This covers allow-admin: false, a path outside allow-roots, a domain removed from allow-tools, and the agent's own configuration directory.
  • A reply too large to send returns too_large (413). A node that cannot switch to the requested account returns failed_precondition. See When the failure came from the node.
  • A refusal gets the same code whether it occurs at the start of a call or partway through it.

Agent 0.4.37 — July 2026​

Execution identity​

  • An elevated file call is no longer limited by allow-roots. It still needs both an Owner/Admin (or a manage grant) and the node's allow-admin. See Node Access Control.
  • The agent's configuration directory stays refused at both identities.
  • On Windows, allow-roots still applies to unelevated file calls.

File search and containment​

  • ⚠ fs_grep and fs_grep_subscribe now work. On older agents they fail with path must be absolute: "". Upgrade the agent to use them.
  • fs_grep now checks every entry in paths against allow-roots.
  • A recursive fs_list, fs_glob or fs_grep no longer lists or reads the files in the agent's own directory.
  • fs_glob with follow_symlinks no longer reports targets outside allow-roots.
  • On a node with a configured user, walks now apply the owner's allow-roots.

allow-roots still does not limit command. To limit execution, remove command from allow-tools or set allow-admin: false.


Router 0.4.36 — July 2026​

  • ⚠ admin: true now needs an org Owner or Admin. A Member gets forbidden. Retry without admin to run as the node's configured account. See Execution identity.
  • On a node's local MCP server, the node's grant decides: manage can elevate on peers, observe cannot.
  • An elevated command_subscribe is refused for the whole cohort or runs on all of it.
  • The fs_* tools now accept admin. fs_grep_subscribe does not.
  • Updating a service that runs elevated needs the same role as creating one. Lowering it needs no role.

Agent 0.4.36 — July 2026​

  • An upgraded node now cleans its config file at startup. No effective setting changes. See Configuration File.
  • The agent writes the file only when its contents change.

Router 0.4.35 — July 2026​

  • You can now call fs_grep over MCP to search a node's files with an RE2 regex. ⚠ It needs agent 0.4.37 or later.
  • Send a progressToken to get each match as a progress notification. Without one, the response holds all hits in matches[]. Read count to know if the search found anything.
  • fs_grep also works on a node's local server at the observe tier. There it always returns the full result.
  • New tool: fs_grep_subscribe searches a whole cohort through the event bus. Read matches with event_tail. outstanding: 0 means the search is complete. See Searching a fleet.
  • event_subscriptions now reports the grep kind.

Agent 0.4.35 — July 2026​

  • The config file now holds only values that differ from the default. Defaults show as commented lines. Hand-written comments do not survive a rewrite. Retired keys are removed with a note that names the new key (event-sources → allow-tools, event-watch-roots → allow-roots). See Configuration File.
  • The config file is now replaced atomically. A restart or power cut during a write no longer loses the overlay slice, the local MCP token or the QUIC endpoint.
  • fs_grep works again on nodes with a configured user. There, matches arrive when the search finishes.

Agent 0.4.34 — July 2026​

Execution identity​

  • ⚠ This agent release makes admin work on command, command_subscribe, file and terminals. On an older agent, admin: true runs as the configured user.
  • File operations now run as the chosen account, with that account's ownership and permissions.
  • An agent that does not run as root now refuses file operations as user. Run the agent as root or clear user.

Node access control​

  • The file tools and fs watches never serve the agent's own directory, for example /etc/nobgp. allow-roots and admin: true do not open it. See Node Access Control.
  • ⚠ allow-admin: false now refuses all work that runs as uid 0. On a node where the agent or user is root, remote execution stops on upgrade. Set an account with sudo nobgp config --user=<account> first.
  • Windows: allow-admin: false now also refuses file operations.
  • The nobgp config warning and allow.warning in nobgp status now say that terminal services are refused too.

Router 0.4.33 — July 2026​

  • ⚠ admin replaces username on command, command_subscribe, service_publish and service_update. false (default) runs as the node's configured account. true runs as the node's ambient identity. A call with username returns invalid_args. Replace username: "root" with admin: true, and remove the field in all other calls. See Execution identity.
  • To run as another account, use su or runas in the command.
  • file now takes admin, and file operations run as the chosen identity. Use file for elevated file operations.
  • A terminal published with username: "root" now has admin: true. A terminal with another account now runs as the node's configured user. To elevate it, set admin: true with service_update.
  • network_directory now shows user and allow_admin for each node. An empty user means admin: false runs as root.

Agent 0.4.33 — July 2026​

  • ⚠ allow-tools and allow-admin now also apply to published terminal services. Plan on-device access before you restrict a node behind CGNAT. See Node Access Control.
  • ⚠ Windows: allow-admin: false now refuses all remote execution on the node.
  • nobgp config now refuses a --user account that does not exist, and refuses --user on Windows. --allow-admin=false now tells you its effect, and asks for confirmation when it turns off remote execution.
  • The --user help text is corrected. --user is the default account for commands and file operations. See the CLI reference.

Router 0.4.32 — July 2026​

  • username: "root" now requests elevation, and admin is removed from command and command_subscribe. A call with admin returns invalid_args. Replace admin: true with username: "root". See Execution identity.
  • Opening an API host in a browser now goes to the docs, for example mcp.nobgp.com goes to the MCP section. MCP clients and API callers do not change.

Agent 0.4.32 — July 2026​

  • nobgp service logs now needs root and shows all agent logs. On Linux and macOS it runs itself with sudo. See Root privileges.
  • Windows: a privilege refusal now names the command to run from an Administrator terminal. For read-only state, use the local MCP server's status tool.
  • nobgp list now reports an unreadable profile directory, not No profiles found.

Agent 0.4.31 — July 2026​

Installation​

  • brew install nobgp/tap/nobgp works again on macOS. Run the install command again.
  • ⚠ The latest download path is removed. Agents older than 0.3.80 cannot upgrade manually. Reinstall them with the install script.

Other changes​

  • Certificate errors caused by antivirus or a proxy now name the product and link to Security software and VPNs.
  • nobgp status now shows TLS interception in router.tls_intercepted, and other VPNs and security products in an environment block.
  • Windows: the network drive no longer disconnects every 30 seconds.
  • Linux: Node.js and Bun now resolve public names on hosts where the agent is the first nameserver. See DNS & hostname resolution.
  • DSL, mobile broadband, Teredo and ISATAP adapters are no longer reported as tunnels. nobgp status no longer waits on the Windows security-product query.

Router 0.4.31 — July 2026​

  • One message the router cannot process no longer disconnects a node. The router logs and skips it.
  • An operational disconnect no longer looks like a credential rejection, so the agent reconnects. Real rejections do not change. See revoked credentials.

Agent 0.4.28 – 0.4.30 · Router 0.4.28 – 0.4.30 — July 2026​

  • A whole-filesystem allow-roots entry now works on Windows.
  • Node grants no longer expire. A grant stays until you revoke it.
  • The Windows installer works again. Run the one-line installer again.
  • ⚠ The install.cmd installer is removed. Use the one-line installer in any Windows shell.
  • RPM-based installs now use dnf when available.
  • One offline peer no longer disrupts other nodes' control channels.

Agent 0.4.19 – 0.4.27 · Router 0.4.24 – 0.4.27 — July 2026​

A node's owner can limit what it serves​

  • allow-tools sets which domains (fs, command) the node serves. It replaces event-sources, and existing values migrate.
  • allow-roots sets which roots the fs tools and watches can use. It replaces event-watch-roots.
  • allow-admin sets whether work can run as root or Administrator. On Windows, allow-admin: false is refused at startup.
  • All three are permissive by default and show in nobgp show and nobgp status. See Node Access Control.

Commands and event bus​

  • command and command_subscribe now take admin or username.
  • ⚠ command_subscribe now runs as the node's configured user, not root. Add admin: true if you need root.
  • Scripts run by the event bus can call nobgp notify.
  • Subscribe calls now return the matched node list, and a selector that matches nothing says so.
  • arch selectors accept arm64/aarch64 and amd64/x86_64.
  • Command results always include exit_code, also for zero.

Tools and platforms​

  • Claude Code can now call tools that take lists or numbers.
  • A failed event_tail no longer loses events.
  • You can use a node name without a network name when it is unambiguous.
  • fs_stat accepts allow_missing, and fs_delete accepts force.
  • whoami no longer returns an empty email for calls through a node.
  • nobgp show no longer prints allow-* settings twice or shows an old quic-router value.
  • On macOS, fs event paths are symlink-resolved, and commands run through the login shell on Unix.
  • macOS service installation, Windows installer elevation and headless Linux installs are fixed. An unpublished version now says so on upgrade.