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
sshover the overlay, a running command — continues instead of dying until its own deadline. Details
See which of your nodes share a LAN
node_listgives each node alan, a key into itslanstable, andselect.lankeeps the nodes on one node's segment, onnode_listand on every tool that takes aselect.net_peerssayssame_lanfor a peer on the node's own segment, andpathfor how traffic reaches it today.- A node now reports its subnet and its default gateway, so
node_listcan 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 readsbasis: "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 readsevent.nodeas text must readevent.node.id. Details - The completion of an
fs_grep_subscribewalk reportsskipped_filesandunreadable_paths, asfs_grepdoes, so you can tell a search that found nothing from one that could not read a path. - When the connection that carried a
commandcloses, the error now tells you to readnode_listto 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
HOMEof its own — procd on OpenWrt — a command or terminal that runs as root now has the home that/etc/passwdnames, 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
ubuntuaccount is gone from that image. Your commands run asnobgpor asroot, as before. - A compute node can no longer reach the cloud host's instance metadata.
0.4.183 — October 2026
A result names the account that ran
- A result that ran on a node now has
user:root(SYSTEMon Windows), or the account that the node's owner configured. You no longer have to infer the account from an absentroot_used. Details - On Linux and macOS, a command that runs as root now has
HOME,USERandLOGNAME, and starts in root's home directory when you give noworkdir, 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_reachnow reportsinterface, the interface the probe left the node by, for examplenobgp0,tailscale0oreth0. A noBGP address in 100.64.0.0/10 is then told apart from a Tailscale address in the same range.net_reach_manyshows it on each row.- When a name resolves outside the noBGP overlay (a Tailscale, LAN or loopback address), the summary of
net_reachand ofnet_reach_manynow 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_listwithview: "health"andnet_metricsnow give the agent version.fs_copynames the node of each end, andservice_updatenames the node of the service.- A file call's summary now states the result, for example
stat /etc/hosts: file, 312 bytesordelete /tmp/x: deleted.
Clearer refusals
- A refusal on a node now writes
root: true, the value you send, and no longer the oldadminor"true"spellings. - When a write cannot replace a file that another program holds open, the error names the file once.
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_reachnow also probes the IPv6 answer for a name and reports it inresolution.address6,resolution.class6andprobe6. An application on the node can use either answer, soopenfor one andtimeoutfor the other is a real finding. Details- A node now reports its IPv6 overlay:
internal_ip6innet_peersandslice6innet_interfaces.net_reachnames the resolver that gave asystemanswer.
ntp_synced agrees with timedatectl
ntp_syncednow has the value thattimedatectlshows as System clock synchronized. ⚠ On agents 0.4.180 and 0.4.181, a host that runschronyreportedntp_synced: falsefor 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
scriptwithshell: "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.exelimit: 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 withfs_writeand 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.comandada@example.comare one person for an invitation, an access request or a node transfer.
Subscriptions and cohorts
presence_subscribenow counts offline nodes too. A watch for two machines that are rebooting no longer saysmatched_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_tailresult now fits a model client. Events left out of anevent_tailresult stay in the queue, andnextpoints to the first of them. - A call to
network_directoryorfileon MCP now names the tools to use in their place.
A Grok Bot computer installs the version of its own channel
- ⚠
ensure.shnow 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 runsudo /workspace/nobgp/ensure.shagain. Details
0.4.181 — October 2026
You scan the QR code, and the link carries the code
sudo nobgp registerandnobgp loginnow print a link that carries its code, so there is nothing to type:https://r.nobgp.com/WDJBfor a registration andhttps://a.nobgp.com/K7QDfor 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 registernow opens the browser in the session you already use.
nobgp login stops before the browser where it cannot keep the sign-in
- ⚠ Run
nobgp loginas yourself, never withsudo: 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 withnobgp 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_rootandforceare 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 isroot, a session handle isid, a wait iswait, a read position iscursor, a count islimit, and a cohort's filters are underselect. 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
nobgpCLI send. - Results use one name each too: the node is
node: {id, name}, a command's state isstatus(running,completed,failed), andadmin_usedisroot_used. Details - ⚠ Upgrade the machine you run
nobgp exec,nobgp network list,nobgp proxy listandnobgp filefrom (sudo nobgp upgrade). An older CLI shows an empty result against this router. Details - ⚠ A cohort
selectthat names no node now takes only the nodes you own. Sendowner: "any"to take every node you may use, as before. Details
You can list your nodes and your session's calls
node_listlists 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_listlists your networks.call_listlists 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_directoryis REST only now. Details
Commands, results and errors
commandandcommand_readtakeuntil: "done": the call returns when the command exits, or after 100 seconds withstatus: "running". Details- A result arrives once, as
structuredContentwith 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_argswith the same body. Details command_read,command_inputandcommand_signalnow name the node that answered.- A
command_subscribeevent carriesoutputas text, each line the exact bytes the command wrote.exit_codeis 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_syncedandntp_offset_ms, innet_metricsand innode_listwithview: "health". ⚠ A field that is absent was not measured: it is never zero or false. node_logsnow 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 asincebound 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 nobgpthere removes/workspace/nobgptoo, so the machine comes back as a new node. Useapt removeto keep the identity. Details
A client can read what this server is before it connects
GET https://mcp.nobgp.com/mcp/server-cardanswers 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-Hostheader a caller sends.
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_directorythen shows that place, withlocation_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_cleargoes back to the place derived from the address, which is kept all along.- Your own place in
whoamifollows 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
archmatches the agent build on the machine, whichnetwork_directorynow reports asinfo.build_architecture: an ARM machine with no floating-point unit isarmv5,mipsleselects the little-endian MIPS build andmipsnow the big-endian one only, and a 32-bit agent on a 64-bit kernel isarmv7. 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_directoryshows both values per node.
Who turned a node's local MCP server on is on the record
node_grant,node_revokeandnode_labelnow write an audit row for each node a call changed, with the targets a grant was narrowed to. Before, a member turning a node's local MCP server on or off left no entry at all. Details
A paged file read no longer waits for bytes it already has
fs_readandfs_copynow 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 withfile_idno longer costs five seconds a chunk, and a copy onto a slow destination no longer runs at half the speed of its link.
0.4.178 — October 2026
A command started with detach now really outlives the call
commandwithdetach: trueis now honoured by the node: the command starts outside the session anddetached_pidcomes 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 —
127for 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 asarmv7, what its kernel reports; from router 0.4.200 it matches it asarmv5. - ⚠ On a MIPS machine whose byte order the install cannot tell, it stops and names the build to install by hand —
mipsfor big-endian,mipslefor little-endian — rather than guessing.
Uninstalling can now remove the node from noBGP as well
sudo nobgp uninstall --purgenow tells noBGP the node is gone, so there is nothing left to delete afterwards. Without--purgethe 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
nobgpitself will not run there is now a published uninstaller:curl -fsSL https://downloads.nobgp.com/agent/uninstall.sh | sudo sh, oruninstall.ps1on 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_peersnow 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. Detailsnoneon 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'snode_reasonnow has a node to report it:clean_stop,upgrade,host_sleep,exit_unrecordedand 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,cloudandtailscaleare 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.
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_reconnectsinnobgp statusthen 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
wpadamong 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_checknow 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_copynow 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 withresource_exhaustedand 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_directoryresult over MCP that would be larger than a model client accepts is now reduced in steps, andtrimmed,omitted_nodes,omitted_networksand each network'snodes_omittedsay 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,osoronline— 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_adminname reached an MCP caller. - Over REST nothing is trimmed: the full directory is always returned.
A retried command no longer risks running twice
commandnow takes aretry_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 itscommand_idand 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_editandfs_writenow 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
commandnow takesdetach: truefor work that must outlive the call — a server, a watcher, a script that restarts the agent itself. The call returns at once withdetached_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.
detachtogether withinputorstdin: "open"is refused: a detached command cannot be fed. - ⚠ The node half ships in agent 0.4.178. On a node below it,
detached_pidis 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_directorynow carries each node'sconnection: 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 survivesbrief. 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_checkcarries the same four new fields beside its backend verdict.info.healthnow carriesstale: truewhen 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_routesnow takes adestination: 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; and0.0.0.0/0or::/0returns one address family. Details- A
net_routesornet_peersresult over MCP larger than a model client accepts is now reduced — host routes and stale peers go first — withtrimmedandomitted_routes/omitted_peerssaying 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
archnow takesarmv5,mipsandriscv64.mipsmatches either byte order, because that is all the kernel reports. network_directorynow reportsbot,cloudandtailscaleper 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.
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 statuson the machine readrouter.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.
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
xtableslock — the lock Docker, Tailscale, k3s andfirewalldtake 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
iptables1.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 anerror— on one machine, one every 15 seconds — which buried the machine's real faults innode_logswithmin_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
chmodon 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 show0644: 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
createcall rather than reporting success and losing the bytes at the upload. Details lnon the drive now says hard links are not supported, where it used to report that the file being linked from did not exist. Details
0.4.172 — October 2026
Each MCP tool now does one thing
- Every operation of the
filesuper-tool has its own MCP tool:fs_fetch_url,fs_lockandfs_unlockjoin the seven per-opfs_*tools andfs_copy. Details commandstarts a session, andcommand_read,command_inputandcommand_signalcarry 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.- ⚠
fileis gone from MCP, andcommandno longer takescommand_id,signaloroutput_offseton MCP or REST. Reconnect your client and use the tools above.POST /api/v1/tools/filestill serves all thirteen operations — includingop=batch, which has no MCP spelling — and the flat body at/actions/execute_shell_commandstill carriescommand_id. - ⚠ Over MCP only the new names exist. Send
rootwhere you sentadmin(adminis refused), and readroot_used,allow_rootandcan_rootwhere you readadmin_used,allow_adminandcan_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_submitreport 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_grantwithtargetsstores them. A grant you narrowed before this release carries no restriction and reaches every peer its owner may use — sendnode_grantagain with thetargetsyou want. Details
An MCP response carries the answer and no diagnostics
- ⚠ An MCP result no longer carries
call_idorduration_ms, and an MCP error no longer carriescall_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_submitnow attaches the call a report is about by itself: name thetooland noBGP adds your last call of it.call_idis 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_nodefor a name whose machine is running starts a second paid machine, a secondcommand_inputsends 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/12or10.0.0.0/8instead 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 showreports 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.
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
INPUTchain 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
INPUTabout twice a minute rather than continuously.
You can invite a person to an organization from an AI client
org_invite_createis now an MCP tool. Whennode_access_grantrefuses 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_sharecall 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.
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
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 onwssuntil its next reconnect.nobgp statusshows 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_metricsnow counts these datagrams indeliver_failedandreturn_fullofdatapath_drops. Before, they had no count. The count of dropped replies (return_full) is on Linux only. Details
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/20from172.16.0.0/12. When the machine already uses that range, it takes a free/20of10.0.0.0/8. It no longer takes a/20inside 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
/20when another product has a route inside it. - ⚠ A Mac or a Windows machine with Tailscale that ran 0.4.160 gets a new
/20at the first start on this version. So does a Linux machine directly on carrier-grade NAT, when the provider's route covers all of100.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
/20covers a private network that the machine reaches through its default gateway, setoverlay-cidrto a/20clear of it.overlay-cidrnow accepts a/20of100.64.0.0/10,172.16.0.0/12or10.0.0.0/8. - A node starts without an overlay only when all three ranges are claimed.
nobgp statusthen 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.
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 statusreported that the address range was fully claimed. The agent now takes its/20and starts with its overlay, and Tailscale keeps working. The same fix applies on macOS and Windows to any product that routes all of100.64.0.0/10through one route. Details - The cause: the agent read Tailscale's route to all of
100.64.0.0/10as a claim on every range it could use. macOS and Windows send traffic to the most specific route, so the agent's own/20wins over that route. - ⚠ Traffic to a Tailscale peer whose address falls inside the agent's
/20now goes to noBGP. This machine no longer reaches that peer. To prevent this, setoverlay-cidrto a/20clear 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.
0.4.159 — October 2026
The flag is --root
nobgp exec,nobgp shell,nobgp proxy publishandnobgp proxy updatetake--root, the same word the tool surface and Roles & Permissions use.--adminstill 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
INPUTchain. 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_logson 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 reportssource: "syslog"with apathbeside it. Details- ⚠ DSM keeps the older generations of that file compressed, and
node_logsdoes not read compressed files. A page that reaches the beginning of the live file names them inunreachable; read them on the NAS withxz -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_directorynow 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,ispandconnection_type. The place is the place of the address, not of the machine. ⚠ispandconnection_typecome from licensed data: read the licence before you show them on a page of your own. Detailsnetwork_directorytakes anosfilter:linux,darwinorwindows.
Commands and files
- A
commandsession now ends when the node's connection to noBGP closes, for example when the agent restarts. The next call answerstarget_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 answersrunninguntil the one-hour idle reap. Details - A large
fs_writeno longer reports a timeout for a write that the node completed: noBGP waits longer for a larger file. ⚠ Atimeouton the last call does not mean that the write failed. Check withfs_statbefore you send the file again. - A large
fs_writeno 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 afileop=fetch_urlfrom a LAN mirror, is no longer refused with403.
Installing on Windows
- The Windows install command now ends in
Invoke-Expression: in the app, inregister_nodeand on these pages. ⚠ Microsoft Defender can refuse the old command, which ends iniex, with Access is denied. Change that word toInvoke-Expressionin 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.
0.4.158 — September 2026
Signing in and registering
nobgp loginandnobgp registernow 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 registerno longer stops withregister failed (401): invalid tokenwhen the sign-in saved bynobgp loginhas expired. It renews it, and when noBGP still refuses it, it continues in the browser. Detailsnobgp listnow asks for your password withsudo, asnobgp statusandnobgp showdo, instead of saying that it cannot read the profile directory. On Windows, run it from an Administrator prompt. Details- The QR code of
nobgp loginandnobgp registeris 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 -fon that machine (on Windows,nobgp upgrade -ffrom 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.
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_updateandnode_access_set, or when you create the node: in the app's registration page, and withaccessonprovision_node. Details - Each node has an access list. Its controllers name members at
useorroot, and a member can ask withnode_access_request. There are six tools:node_access_list,node_access_set,node_access_grant,node_access_revoke,node_access_requestandnode_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_directorytells you what you hold on each node, inmy_access:control,root,useornone.- Root is a separate grant. The controllers have it. Anyone else gets it from a
rootentry, which needsconfirm_root: trueafter a warning, or from a name on a root terminal, in that terminal only. Sharing never gives root. A node whose owner setallow-root: falserefuses root to everyone, controllers included. Details - "Elevated" is now called root everywhere. On Windows, root means administrator. The fields are
root,root_used,allow_rootandcan_root, and the machine setting isallow-root. The oldadminnames still work. ⚠ Do not send both names of one field in one call: that isinvalid_args. ⚠ On the machine, where bothallow-adminandallow-rootare 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_updateandnetwork_key_delete. Another member gets install commands with no key fromregister_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_transfergives a node to another member of its organization, named by email. The result lists each root grant that the new owner inherits.node_channel_setsets 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_memberswithservice_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
useorrootentry does not give it, and neither does sharing. Anyone at the machine can read it withnobgp service logs. Details node_logsreads the log as the agent itself. It needs noroot: "true"retry, and it works on a node withallow-root: false. Thelogsdomain ofallow-toolsstill 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-rootincluded. 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
qalso finds the actor's name. A call that fails over MCP records its error code. Details
A node's local MCP server
node_grantturns 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. ⚠ Theobservetier 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 registerandnobgp loginprint a page and a four-character code. Type the code atapp.nobgp.com/register(a machine) orapp.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-toolsrefuses a value it cannot read. A value that is not a domain leaves the node serving nothing, andnobgp configrefuses it.logsis a new domain, added once to a profile that lists its domains. Check yours withnobgp show. Details sudo nobgp config --peer-loopback=falsekeeps 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
nobgpcommands that read it from an Administrator prompt. On Linux and macOS,rootowns it, so those commands needsudo. - A value that you save with
nobgp configstays saved. Before, a value saved during a registration or a restart could be lost: if you setallow-root: falseor another owner setting at such a time, read it back withnobgp show. A lock file (.default.yml.lock) now sits beside the configuration file. Details nobgp mcp installsays who can use the local MCP token, and writes each client configuration0600. Detailsinstall.shdoes not downgrade an agent that is ahead of the stable channel. SetNOBGP_VERSIONto install a specific version. Details
Fixes
fs_copyand transfer URLs follow a symlink to a regular file. ⚠ Arecursivecopy does not follow links inside the folder: each link is a failed row. Detailsfs_listandfs_statentries carry atype. An absenttypemeans unknown, not file. Detailsfs_readrefuses a folder, a pipe, a socket or a block device at once, instead of blocking.net_reachsays a name is not resolved yet when the lookup is still running, instead of saying it does not resolve.- A late poll of a
commandsays when it exited, with its exit code. Details - A
commandsession 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
needrestartrestarting the agent in the middle of it. - A missing path is no longer logged as an error on the node, and answers
not_foundon 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.
0.4.151 — September 2026
A recursive listing no longer reports a folder it could not read as empty
fs_listwithrecursive: trueno longer answers empty for a folder that is missing, that it cannot open, or that is not a folder at all. It now fails withnot_found,permission_denied, or an error naming the path as not a directory — the same answers the call withoutrecursivealready gave. Details- ⚠ Code that reads a zero-entry recursive listing as an empty folder now has an error to handle.
filewithop: "list"answers the same way.
A shared drive that fails to mount on a Mac or Linux says so
- A
webdavmount attempt that runs and fails is no longer reported as the host having nothing to mount with.nobgp statusnames the failure underfs.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_directorynow filters on what a machine has:min_cpu_count,min_total_memory(in bytes),gpu_kindandhas_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_gpuboth 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, orhas_gpucontradictinggpu_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_copyonto the shared drive or a machine's storage area now refuses a destination named.nobgp-trashor.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
commandorfilesession 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.
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_logswithmin_level: errorshows 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.
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
launchdstarts 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 restarton the Mac, or let the next upgrade do it. nobgp service restartno longer leaves a Mac without a service whenlaunchdreports 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.
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-9D84answers toWiiM-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_reachon that machine reports the device's own name asresolution.lan_name, so an answer says which host it reached.- The machine owner's
lan-nameslist 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
webdavmount is now checked against the version that machine read. One noBGP refuses reaches the operating system's client as412 Precondition Failed, the other machine's version stays on the drive, and your bytes are kept on the node —nobgp statuslists them underfs.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 statusnames such an attempt underfs.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 restarton 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 restartno longer leaves a sysv machine stopped when the shutdown takes longer than the init script waits for it.- On Synology DSM,
nobgp service restartrun through noBGP now restarts the service. Before, it refused, because DSM has nosystemd-run. Details
Free space where your commands actually run
net_metricsnow reportshome_disk_free_bytesbesidedisk_free_bytes: free space on the filesystem holding the home directory an unelevatedcommandstarts in. On a machine with/homeon its own storage that is a different disk from the onedisk_free_bytesmeasures.network_directorycarries it too, in each machine'sinfo.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_readableinnetwork_directoryis now withdrawn together withfs_mount, so a machine with nothing mounted shows neither and the two read as one answer. Before,mount_readablekept the last value the machine sent, so one whose drive had gone went on reportingtruebeside an absentfs_mountuntil 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
pathsonfs_copyworks 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
- Continuing a
commandorfilesession by its id, and calls against a network's shared drive or a machine's storage area, are now recorded in the organization's audit log. None of them names a machine, so none of them had an organization to be filed against and each was dropped. Details
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_nameorhome_disk_free_bytesand refuses the whole answer rather than dropping the field, sonet_reachandnet_metricsreturn an error for those machines.
0.4.146 — September 2026
What a node dropped from a peer is counted
net_metricsnow counts five more kinds of dropped packet indatapath_drops:protocol,icmp_type,malformed,no_deliveryanddeliver_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_failedrather than dropped uncounted. - ⚠ A self-hosted router must run 0.4.174 or later before its machines run this agent, or
net_metricsreturns an error for them.
A healthy node no longer reads as error while it mounts
info.fs_backendinnetwork_directorynow reports only a mount attempt that has finished. Before, a node publishederrorbefore 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_mountis withdrawn meanwhile — so a backend with no mount point beside it reads as "mounting". ⚠info.mount_readableis not withdrawn with it: it keeps the value the node last reported until the node reports again, so during a remount it can still saytrueabout a mount that has gone. Readfs_mountfor that, notmount_readable.
A new file shows its real size in dir and Explorer
- On a
winfspornfsmount, 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 whileGet-Itemon the same name was right. Details
An old nobgp.com service URL reaches the service again
- A
https://<name>.nobgp.comURL for a service you published now redirects permanently tohttps://<name>.nobgp.link, keeping the path and the query, so an old bookmark or a link you shared arrives. AGETgets a301and any other method a308, 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.comthat has never been a published service now returns404. ⚠ Before, such a host reached noBGP's own endpoints andhttps://<name>.nobgp.com/healthanswered200 OK, so an uptime check pointed at an old service URL stayed green while the service was unreachable — point it at thenobgp.linkURL.
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.
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 thenobgp.comthe dashboard and the API use, so a page your service serves can no longer write a cookie the dashboard reads. Details - ⚠
<name>.nobgp.comno 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 frompublic_url. - ⚠ Your backend now receives cookies named
workos-access-token,workos-refresh-token,workos-session-idandnobgp-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 onnobgp.linkcannot set one for yours. Your backend receives neither it nornobgp_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
POSTto/.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 registeron 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_KEYasks 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 registerover SSH opens nothing on anyone else's. - On a Mac that is already enrolled, run
sudo nobgp registerat 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, thennode-namein the configuration file, thenNOBGP_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, socurl … | NOBGP_NAME=web-1 shenrolled 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-windowsnow 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 statusreportsnetwork.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 withpermission_deniednaming the socket, andservice_checkshows 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_bytesinnetwork_directory'sinfo.healthand innet_metrics. Free memory, which older agents report asmem_free_bytes, reads near zero on a healthy Mac and about four times low on Linux. network_directorynow reportsinfo.total_disk, the usable size (used plus available) of the filesystemdisk_free_bytesmeasures, 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.
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_metricsnow counts two more kinds of dropped packet indatapath_drops:return_fullandqueue_full. The node must run agent 0.4.142 or later.
Copy a directory or a set of files in one call
fs_copytakesrecursive: trueto copy every file under a directory, orpathsto 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, andcompleteis 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_ADMINor/dev/net/tun, the Linux agent now starts without the overlay instead of stopping.command, the file tools andnobgp statuswork, andnobgp statussays 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/sysis 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_peersshows 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.whoamilists the tools you can call and their arguments (tools), so a client with an old tool list can see what it is missing.node_logson 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_deleteno 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-Forheader. - On Windows, an update restart lets the agent finish its own shutdown instead of stopping it by force.
- A
transport-familysetting 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> -fstill 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
/, andopkg remove nobgpremoves the package directory.
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
pingto the node is answered by the node itself. - The agent's own listeners,
rpcbindon 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-firewallhas 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 statusandnobgp showsay that the host firewall does not filter peers.network_directorynow 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_directoryshows an update that a node was offered and has not installed (info.upgrade). When the node says why, the reason is there too, for exampleauto_upgrade_offorinstall_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_statusreadsbelow_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
pingto such a device, andnet_reachon 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_preconditionand names your path.fs_copyandfs_grep_subscribealways say what failed at the end that failed. - A
fs_greporfs_grep_subscribepath that is absolute only on another platform, for example/etc/os-releaseon a Windows node, is reported asnot_foundfor that path, and that node completes its search. Before, the search failed on that node. - A refused
fs_editis no longer written to the node's log as an error.
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-resolvedhosts 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_reachreports such a name assource: "overlay"with the class of the LAN address (usuallyclass: "lan"), where it used to reportsource: "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 registerprompt 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.
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
AAAAas well asA. 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
AAAAonly. 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 withoverlay-ipv6: false, on the machine or withnode_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
mtuor 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>_NATandNOBGP_<interface>_FWDchains, the matching OpenWrtfw4rules, and thefirewalldbinding of the noBGP interface to thetrustedzone. - ⚠ The
lan-deliverykey is retired. The agent removes it from the profile, and--lan-deliveryandNOBGP_LAN_DELIVERYare 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.0or::— 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_metricsnow reportsdatapath_drops, the overlay packets a machine refused, by class. ⚠ A non-zeropanicscount 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_metricsreturns an error for them.
Registering a machine finishes in the browser
sudo nobgp registerprints 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,
registerand the install script now say that no service runs the agent. WithNOBGP_EXIT_NO_SERVICE=1, that case exits4. sudo nobgp registerandnobgp loginsay 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.confthere. 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
--pipeupgrades again. ⚠ If a node showed an old version while online, upgrade it once. Details - An OpenWrt machine now answers
AAAAfor a peer's name. - ⚠ On Windows,
nobgp service restartinside acommandsession now refuses and names the ways through. Before, it printedscheduledand nothing restarted: restart a node you restarted that way from the machine itself. Details nobgp registerno longer freezes in a background shell, and a command that ends without an exit no longer stalls the machine.inputsent while another call closes the same session's stdin is written first, or refused withinvalid_args. Details- A Mac no longer counts its own broadcasts as dropped replies in
net_metrics. network_directorylists a host service whatever case its type is spelled in, and asourceword noBGP cannot use costs only that field, never the service itself.
0.4.128 — September 2026
You can ask a node whether it reaches a name
net_reachresolves a name on one node and probes what it got back, and says which resolver answered and which node delivers it. It replaces thepingandncrecipes, and answers the part those cannot.net_reach_manyasks 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
observetier. - 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 tocommand.
A command that reads stdin now finishes
- A
commandsession's stdin is at end of file unless you ask for a pipe, soausearch,catwith no file,sshand 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 aninputon the call that starts it. Without one it exits immediately. close_inputputs stdin at end of file, optionally with a finalinputon the same call, which is what makessortandwcusable.- 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_inputcomes back withoutstdin_closed. Upgrade the agent, or stop such a session withSIGKILL.
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.*,!routerserves everything but one device, andoffserves 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_reachreports it asresolution.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
firewalldincluded. ⚠ On afirewalldhost the agent puts the noBGP interface in thetrustedzone 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_directorycarries each node'sinfo.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=falsereports 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-announceregisters each peer as<name>-nobgp.localwith 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 registernow 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 statusreadsquic_pin: learnedstraight 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_subscribewithadmin: "false"also counts, before anything runs, the nodes that have no unelevated identity. Details
A PowerShell script can call another script
- A
scriptsent withshell: "powershell"now runs with the execution policy bypassed for that process, so a.ps1file 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
401challenge now name the scopes, includingoffline_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-Afterinstead of401, 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 -9or 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
adminnow 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'sadmin_usedsays which one ran. One call now covers a fleet whose nodes differ. Details - ⚠ An omitted
admincan therefore elevate, and a caller who may not elevate is refused withforbiddenon those nodes. Sendadmin: "false"when the work must not run as the superuser. admin: "auto"is now refused withinvalid_args. Omitadmin, 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 omittedadminwould run elevated, omittingadmin. It no longer namesadmin: "auto". Details
The Windows install command carries the key again
register_nodereturns a Windows command that installs with no prompt, so an unattended install works again. It no longer returns a separateregistration_keyfield. 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-imageand/usr/share/nobgp-image/packages.tsvare gone, andnetwork_directoryno longer reportstask_image_nameortask_image_version. Compute Nodes describes the image and lists its packages.- ⚠ If a script reads either file, ask the machine instead:
cat /etc/os-releasefor the release,apt list --installedfor the packages,nobgp versionfor the agent.
0.4.126 — September 2026
The Windows Firewall rule is named after the profile
- The agent's inbound rule is now
noBGP-<profile>, for examplenoBGP-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 removenow removes the rule of the profile it removes.nobgp uninstallremoves every profile's rule and any device-named rule left by an earlier release.- If the agent cannot read the firewall rules,
allow-overlaynow leaves the rule as it is.
nobgp mcp install no longer overwrites another nobgp entry
- If a
nobgpentry in your Claude configuration is not a local node's, for example the public server,installnow stops and asks you to rename it, for example tonobgp-public.--yesdoes not skip this. Details uninstallleaves that entry in place, andnobgp mcp statusreports it as not registered.
Stopping a machine tells you whether its name starts it again
task_stopnow returnsrestartable_by_name(router 0.4.151).falsemeans that provisioning the name does not bring this node back, andnotes[]says why.
A command waiting on stdin is explained
- The
commandtool description now says that a command that reads stdin waits until the session ends, and how to redirect stdin on each platform. Details
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.
0.4.124 — September 2026
A Windows machine can keep its own firewall policy
- Set
windows-firewall: respect-windows, or runsudo 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. Thecommandtool, 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 uninstallremoves 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-imagenames the image and its version./usr/share/nobgp-image/packages.tsvlists 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_stopstops 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
smallhours or 83mediumhours. - 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_nodenow takesnetwork_idas well asnetwork_name. Send one, not both.- The
register_nodeone-liner no longer usessudo. Run it as given. ⚠ Before, thesudoform wrote the full registration key to the system log of each machine installed with it.
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 statusstill 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 usecommand_subscribe. Details
0.4.121 — September 2026
Large files are copied and read in full
fs_copyandfs_readno 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 nogpublock, because it does not check for a GPU yet. A Windows node below 0.4.121 showsnoneuntil it upgrades and reconnects. unifiedis now absent when the machine could not check.falsenow 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.
eventsis now always a list. event_tailnow acceptswaitas well aswait_seconds.- A KVM now publishes the attached machine under the hostname from its DHCP request.
--nameis repeatable, and--no-lease-namepublishes 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.
redactnow covers every place the router could write command text.
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) anddisk_free_bytes(free space where the agent runs). On a container, CPU and memory are the host's figures.- A
gpublock with the interface (cuda,rocm,metal,rknpuornone), the device count,memory_bytesandunified. - ⚠
nonemeans the machine found no accelerator. Nogpublock means the machine did not answer. Do not read a missing block as "no GPU". - When
unifiedis true, the capacity for a large job istotal_memory. Otherwisememory_bytesis the card's own memory.rocmandrknpunodes report no memory figure. An Intel Mac reportsnone. - 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
workdirand 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_sha256only on a chunked upload, not on a single-call write.
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 logsornode_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.
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
/tmpfreed 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
admingoes insidesessiononcommand, insidesourceanddestinationonfs_copyand onfilewithop: "copy", and at the top level everywhere else. Details- Set a command's
idle_timeoutto the total wait you accept, not to the gap between lines.
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 resolvestill 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_receiveandcontrol_transmitfigures 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 Band$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_emptyfor 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_capandcreditdescribe this. Do not build oncredit_billed. It always readstrueand will be removed.
Sign-in links keep your tokens in the noBGP app
- 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
infoline 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_buyincludes 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_centsfalls. Expired credit stays spent.
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 nowdebug. A NAS can let its drives sleep again. See Log levels. - To see peer presence, use
network_directoryorpresence_subscribe. node_logsandnobgp service logscan 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-familyorNOBGP_TRANSPORT_FAMILY. See Address family. autois the default and does not change behavior.v4andv6try 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: offor 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
._namefiles, so extended attributes, Finder tags and resource forks survive. See What travels with a file. cpfrom 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.dbandautorun.infare still discarded. - A sidecar follows the case rule.
An empty credit balance stops running machines
- On a paid plan, running provisioned machines stop within about ten minutes when included compute is used up and the credit balance is empty. They stop as at a deadline. See When the compute budget runs out.
- Buy credit, then provision the name again to bring the machine back. The node keeps its identity, name, labels, grants and storage area. The local disk is lost.
- The allowance mails now name the stop.
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_exhaustedwithlimit_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=purchaseslists this period's purchase attempts, failed ones included. Useperiod(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.
creditstatus showspending_purchase_centsandoldest_pending_purchase_at. Do not add the pending figure topurchased_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_clearedandbilling.spend_cap_cleared.org_audit_listreturns them. - A lapsed payment keeps both settings.
Smaller changes
cancel_at_period_endon the billing summary now shows portal cancellations.org_createnow puts a new organization on Free, and the three-free-organizations limit counts it.
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_idfromprovision_node. - ⚠
max_hourscounts from now, not from when the machine started. Omit it to reset to your plan's default.0removes the deadline, except on Free. - A shorter deadline does not stop the machine now. Use
deprovision_nodefor 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_directorynow showstask_deadline_atper node. Do not cache a remaining time. The deadline can change.
Enterprise machines have a deadline
- ⚠ An Enterprise machine now stops after 24 hours by default. Set
max_hours: 0for no deadline. Machines already running do not change. See Every machine has a deadline and How long it runs.
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=buyand automatic refills now complete. Failed attempts charged nothing, and their reservations are released.
Usage is paid from credit on noBGP's own routers
credit_billednow readstrue. 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=buyby 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_centsis new oncreditstatus. Headroom isspend_cap_centsminus this field.
An auto-reload trigger of zero is refused
- ⚠
credit op=auto_reloadnow refuses a trigger of0. To refill when the balance is empty, use 1 cent. reload_centsmust 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 andnobgp statuskeep working, so you can repair the machine remotely. Before, agent 0.4.111 exited and restarted again and again. nobgp statusnow shows the reason undernetwork.overlay. Seenobgp status.- ⚠ To bring the node back onto the overlay, free space in
100.64.0.0/10or pinoverlay-cidrto 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/20by default. It keeps a pinned or previously recorded/20with a warning, and reports the error undernetwork.overlay. - A pinned
overlay-cidrmust still be a/20inside100.64.0.0/10and 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 onlymain. 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/10is 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
/20elsewhere. - If another product claims all of
100.64.0.0/10, the agent logsno free /20 slice available in 100.64.0.0/10 (host is fully claimed). Free space in the range to use the overlay. Pinningoverlay-cidrdoes 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_renamechanges a node's name and keeps itsnode_id, labels, grants, services, public URLs and storage. Give the new name innew_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_nodenow 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_offlineon the response. If it isfalse, pollnetwork_directoryuntil 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=buynow uses the subscription's payment method, then the customer default, then the only attached method. The billing summary shows the same method, with itstypeand, for Link or a bank, anaccount.- 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
creditstatus now hascredit_billed. It tells you if this deployment spends the credit balance on overage. On noBGP's own routers it isfalse: overage is invoiced, andop=buyreturnsfailed_precondition. See Usage credit.- The balance is spent only when both
credit_billedandcredit_enabledaretrue. - Every
creditcall now writes an audit entry that names the operation:billing.credit_status,billing.credit_buy,billing.credit_auto_reloadorbilling.credit_spending. A refused charge is also recorded.
Agent 0.4.110 — September 2026
- On macOS the agent no longer switches on the
pfpacket filter. Before, it could enablepfand leave it on. - ⚠ Upgrading does not turn
pfoff 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 debugto see the line, or readnet_metrics. - You no longer need to lower
log-levelto stop these writes. See Log levels.
Router 0.4.117 — September 2026
- A provisioned machine now stops at a deadline.
provision_nodetakesmax_hoursand returnsdeadline_at. If you omitmax_hours, the machine stops after 24 hours on Free, Pro and Business. The maximum is8760(one year). See How long it runs. - On Pro and Business,
max_hours: 0runs 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 registernow 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. Seenobgp register.- You no longer need
--nameas a workaround. - A key conflict now names the node that holds the key, instead of
enrollment failed. Seeenrollment 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.enabledis required. Withenabled: false, noBGP keeps the balance and slows the organization at its allowance. creditstatus now returnscredit_enabled,spent_this_period_centsandperiod_end.- On noBGP's own routers, the balance is not spent today. Overage is invoiced. See The meters.
create_checkoutno 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
- On macOS, a node that an unexpected signal stops now restarts after about 8 seconds. See The node went offline and stayed offline.
- ⚠ On macOS,
sudo launchctl stop nobgp,launchctl killandpkillno longer stop the node. Usenobgp service stop. - Linux and Windows are unchanged.
- When DNS fails, the agent now alternates IPv4 and IPv6 addresses. A dead IPv6 address no longer blocks the working IPv4 addresses. See Node never reconnects after the site's IPv6 prefix changes.
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 stops400 Request Header Or Cookie Too Largeerrors 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
billingis a new Owner-only read on the REST surface. Page invoices withinvoice_limitandinvoice_starting_after. See Your plan, your card and your invoices.- ⚠ Read
cancel_at_period_endwith the status. A cancelled subscription staysactiveuntil the period ends. create_billing_portaltakes an optionalflow:payment_method_update,subscription_updateorsubscription_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 statuslists the profile asunavailable. Aninterface:name that does not exist makes the agent wait indefinitely.
Agent 0.4.106 — August 2026
- A restart no longer unmounts the drive that the new agent has just mounted. This applies to
fuse,nfsandwebdavon Linux and macOS. See A teardown belongs to the process that made the mount. - On Windows,
SIGTERMorSIGKILLon a terminal session now stops the process and everything it started.
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_nodealso suffixes a contested name. Readreadopted_node_idto see what was re-adopted.
Other changes
node_logsnow 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
node_logsno longer reports a complete, clean log whenjournalctlhides the agent's lines from an unelevated call. It now returnsfailed_preconditionnamingadmin: "true". Retry withadmin: "true".unreachablenow also reports when an earlier log source refused your identity. It rides every page.- On a machine whose
/var/logis in RAM,node_logsagain reads the journal orlogreadbefore the agent's own mirror. The first read after an upgrade no longer returns a near-empty page as the whole log. See The agent's log starts empty after every reboot. - A refusal for unelevated never means root no longer waits for a slow account lookup.
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_atis removed fromnetwork_directory. Readonlineandoffline_atinstead.- 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_nodeno longer refuses a name that is online or has an open provisioning task. It uses the next free name,<name>-1to<name>-8.- ⚠ Read
node_namein 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.
A node's health reading survives a flapping link
info.healthand thehostblock ofnet_metricsno longer disappear when a node reconnects. Only a reboot hides the sample, for about 90 seconds.
Router 0.4.111 — August 2026
task_idinnetwork_directorynow 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
readybefore 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. forbiddennow means provisioning was revoked for your account. You can still usedeprovision_node.
net_metrics health belongs to the current session
- The
hostblock 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
unreachablenow names each cause: the log mechanism's reach, yoursincebound, 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-nameon 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
healthsample 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
sourceandpathfirst. Details. - Known issue: A
sincebound uses the node's clock. On a machine with no real-time clock, read a boot withsinceomitted. Details.
feedback_submit is not only for unattended sessions
- Use
feedback_submitalso when a human is in the session.
Router 0.4.108 — August 2026
network_directorynow reportsonline_at, the start of the node's current connection. A value later than your action means the node came back.- ⚠
online_atis not a liveness flag. An offline node keeps the start of its last session. Read it withonline. - 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, newcommandsessions and file reads and writes stop. - Drive URLs and mounts return
402 Payment Required. Tools returnresource_exhaustedwithlimit_type: "bandwidth".file op=fetch_urlstill 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
mediumhour uses three hours, alargehour six. Provisioned compute. - New classes:
large(2 vCPU / 4 GiB) at $0.12/hour andxlarge(4 vCPU / 8 GiB) at $0.24/hour. - Known issue: a
largeorxlargerequest can be accepted and then fail to start. - Any member can read usage per class with
compute_usageon the REST surface.
Reaching a limit suspends a machine, it never destroys one
- A compute limit, the spend cap or a lapsed payment now stops the container. The node keeps its identity, labels, grants and storage. Provision the same name to resume. The container's writable layer is not kept.
- The suspended state was removed in 0.4.112. When noBGP stops a machine.
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 ormedium(1 vCPU / 2 GiB) at $0.06/hour. The default issmall. Compute classes. - ⚠
cpuandmemorynow returninvalid_args. Sendclassinstead.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,fileandfs_*,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_readcall 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/login RAM, the agent log now survives a reboot. The agent writes<config-dir>/nobgp.log, up to about 20 MiB. Linux only. Details. node_logsnow says when yoursincebound 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_reconnectsdo 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, thennobgp service restart. Details.
Agent 0.4.100 — August 2026
- On a packageless Linux with busybox init,
nobgp service installnow works and the agent starts at boot. - ⚠ If 0.4.99 left the service half-installed, run
nobgp service startornobgp 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 upgradeworks. - On a read-only rootfs, set
INSTALL_DIRto 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. Usewinfsp, or raiseFileSizeLimitInBytesand restartWebClient. 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_idinnobgp statuson the console of the peer. - The new
nobgp peerscommand lists the pinned keys. Add--jsonfor scripts. It also works when the agent is not running. - The new
peer-key-pinningsetting takeswarn(the default: log atERRORand continue),enforce(refuse the session) oroff. 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. Useenforceonly 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-allresets all peers. - With
warn, the node reports the mismatch on every session until you resolve it. - The pins are in a
<profile>-peerkeys.jsonfile 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-pinningwithnode_config_set. Set it on the machine withnobgp 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
wssdo not change. - On QUIC,
router.connectedinnobgp statuscan 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
nobgpfail withAccess is deniedfor accounts that are not Administrator. The next upgrade repairs a machine that has this problem. See the troubleshooting entry. info.mount_readableinnetwork_directorynow changes when a mount fails. The node checks it on every cycle, also while it retries the mount.- ⚠
webdav-proxy-ownerscannot be enforced. A node with this key now refuses all callers to the shared-drive proxy and logs anERROR. 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. Thecurl … | sudo shform 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: trueinnetwork_directory. A sweep closes these records every hour. - For a record that the sweep closes,
offline_atis the time of the sweep, not the time of the disconnect. presence_subscribesends noofflineevent 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.connectedinnobgp statusnow changes tofalsewhen the node loses the router.- The new
router.sincefield shows when the current state started. The newrouter.offline_for_secsfield shows how long the link is down. Both fields are also in the local MCPstatustool. - 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.transportandrouter.remote_addrshow 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
fs_grepnow reports the paths that it could not read. This is the agent half of router 0.4.96.
Router 0.4.96 — August 2026
Searches report what they did not search, and Windows copies over WebDAV work.
A search tells you which paths it did not search
- ⚠
fs_grepandfs_grep_subscribenow returnunreadable_pathsandunreadable[]. Each path has a reason:not_found,permission_denied(retry withadmin: "true") orunreadable. - Trust a zero result only when
skipped_filesandunreadable_pathsare both 0. A node below agent 0.4.96 always reports 0, so check itsinfo.agent_version. See A zero is only a zero.
Tool descriptions warn about Windows script encoding
fs_write,fs_editandfilewrite UTF-8 without a byte-order mark. Windows PowerShell andcmd.exedo not read such a script as UTF-8, so characters outside ASCII break.- ⚠ Keep a
.ps1,.bator.cmdscript to ASCII. Or send it throughcommand'sscriptfield withshell: "powershell".
Fixes
- A copy onto a Windows
webdavdrive no longer fails with0x80070021.Copy-Item,cmd.exe copyand an Explorer drag now work. A lock on a directory is still refused with423.
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_logswith apatternthat matches nothing now returns an empty result, not an error.- Each page now has a
scannedcount of the lines it examined. - When the log goes back no further, the search ends with success and an
unreachablenote. To read more, runnobgp service logson 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_setnow writes only operational keys. It refuses all other keys, includingrouter,insecure,quic-cert-pin,encryptandauto-upgrade.- Files in a renamed folder on a
fusemount can be read at once.node_logspaging 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 closedas 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,doneandduration_msare 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,retryableanddetails. An error names its node, for exampletarget_unreachablewithdetails.offline_at. adminon the tools that run something is now a string:"true"or"false". Every result reportsadmin_used.- You can name the node with
node_id, ornetwork_name+node_name, at the top level of the arguments. Do not also send the nested form, or you getinvalid_args.
New tools
node_logsreads the agent log of a node. It takeslines,since,min_level,patternandcursor.service_checktells you if a service backend is up:reachable,unreachableornot_applicable.fs_copycopies one file between two nodes in one call. Neither node needs a route to the other.node_config_getandnode_config_setread and write the settings of a node over its control channel. Each key returnslive,restart_requiredorrefused.feedback_submitsends 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
commandoutput again. Sendnext_output_offsetback asoutput_offset. The newest 1 MiB is kept.idle_timeoutis limited to 100 s. command_subscribetakesscript,shell,workdirandenv, so one dispatch runs on Linux, macOS, Windows and OpenWrt.- A signal result now shows
signal_delivered,signal_mechanismandsignal_target.stderris now separate fromoutput. - Output from Windows with characters outside ASCII now comes back as UTF-8.
- ⚠ On macOS, an
admin: "true"call uses thePATHof root, which does not include/usr/local/bin. If you get exit 127, use the absolute path.
Files
- ⚠ The default
max_bytesoffs_readis now 32 KiB, down from 256 KiB. Usetruncatedandnext_offsetto read the rest. transfer: "url"gives a short-lived/xfer/URL that a browser, CI orop=fetch_urlcan fetch. It works from router 0.4.87.expected_sha256is now checked on the shared drive and on node storage areas. A mismatch returnsprecondition_mismatchand does not change the file.- A failed write now removes the parent directories that it created.
fs_grepreturns its matches again when you send aprogressToken.- A recursive delete inside
/tmp,/var/tmporC:\Windows\Tempno longer needsforce: true.
Watching a fleet
fs_subscribeandpresence_subscribetakekeep_seconds, up to 24 hours.presence_subscribeadds areadyevent when a session holds for 5 s. Wait forreadyafter a provision.- A noBGP write shows in
fs_subscribeascreate, notwrite. net_metricsnow reportshost.cpu_percent,mem_free_bytes,load1andat.load1is not available on Windows.network_directorynow showsinfo.fs_mountandinfo.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 statusshows anfs.unreadableline 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.conflictsinnobgp status. - File locks now survive a router deploy.
- A delete now answers at once. The names
.nobgp-trashand.nobgp-upload-*are reserved. - The Free storage allowance is enforced:
507 Insufficient Storageon the drive, andresource_exhaustedonfs_write,fs_mkdirandfs_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_reconnectsis nowrouter.control_reconnects. - A node whose DNS fails stays reachable.
nobgp service restartnow schedules the restart and returns. Exit 0 means that the restart is scheduled.- A change to
fsin 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_limitedwithdetails.retry_after_ms. - The spend cap now limits only overage. A cap of
0means 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 statusaddsfs.no_fallback,fs.locking,fs.conflictsandfs.unreadable.network_directoryaddsinfo.healthandinfo.writable_roots./mcpand/api/v1support gzip.- Provisioned node images run
tinias 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 restartnow schedules the restart outside its own process tree and returns about two seconds before the restart. Exit 0 means "scheduled", not "back up". Confirm withnobgp 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 statusrenamesquic_reconnectstorouter.control_reconnects. Read it besiderouter.transport.
The shared drive
nobgp statusshows a newfs.no_fallbackline 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_interfacesnow returns anoverlayblock: 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
commandtakes ascript: a whole script body with real newlines and no escaping. Sendcommandorscript, never both. On Windows the body runs as a batch script, or as PowerShell withshell: "powershell", without the 8191-character line limit.scriptis refused on a node that never reported its OS. Sendcommand, or setshell: "powershell". A body over the platform limit (about 9 KiB batch, 12 KiB PowerShell, 117 KiB shell) is also refused. Write it withfs_writeand run its path.- A Windows call that exits 255 with no output and no
shellnow returns ahintwith the two ways through.
Diagnostics
- ⚠
net_interfacesnow returns anoverlayblock with the node's TUN interface, its/20slice, and the address its name resolves to on that node. The node must run agent 0.4.83. Do not use the interface'saddrsfor 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_subscribenow takesadmin, asfs_grepdoes. 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: autoselects 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. Setfs: webdavto keep WebDAV, orfs: offfor 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.txttoReport.txt, now works.
File locks on the shared drive
- An interrupted copy no longer makes a file unwritable. Copying a file such as an
.msiin Explorer no longer fails with0x80070021. 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
LOCKand afile op=locknow 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
nfsmount 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_sha256tofs_writeto 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 statusandnobgp showreport the result. - New
fsconfig key:auto | off | nfs | fuse | webdav | winfsp.autois the default. The agent uses an explicit choice or refuses it, and never replaces it. fs: offmounts nothing and logs why once.nobgp showreports thefsselection,fs-backendandfs-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 example30s. 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.txtandCASE.TXTcannot 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 asInput/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_lockinginnetwork_directoryshows 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
nobgpdaemon 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 withstorage: 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: winfspto 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.
nfsstays 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_directoryshows 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 registernow re-registers a node whose token expired.
Reliability
- A restarted agent no longer stops its node accepting sessions with
destination recently closed. fs_readnow reads files larger than 1 MiB on the shared drive and a node's storage area. A partial page returnsdone: false. Continue fromoffset + size.
Agent 0.4.55 — August 2026
Files that went missing from the mounted drive on macOS and Windows are back.
- Listings under
node/andnetworks/<name>/no longer lose entries on macOS and Windows, at any depth. - A network name that contains a space now lists correctly.
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, andnetworks/, one folder per network. A file at/mnt/nobgp/report.pdfis 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.
Router 0.4.56 — August 2026
Your assistant can read and write noBGP's own file storage, without going through a node.
fileand thefs_*tools can now reach a network's shared drive (a network and no node) or a node's own storage area (storage: truewith 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,mkdiranddeletework on storage, up to 1 MiB per call. For a larger file, use the tree's HTTPS URL.storage: truerequires the node id, not its name.- ⚠ On storage,
deletealways removes the whole subtree, andadminis 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_urlinnetwork_directorynow 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-ownerskey limits the local WebDAV proxy on127.0.0.1:19840to 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.
Router 0.4.53 — August 2026
The shared drive is now a real filesystem, and file names are case-sensitive because of it.
- ⚠
README.mdandreadme.mdare 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
commandfromallow-toolsnow asks for confirmation. A non-interactive run, includingnobgp configover MCP, is refused unless you pass--yes. Undoing the change needs console, RDP or SSH access. --yesanswers 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: falsecalls are then refused (unelevated never means root). A reinstall or registration sets the account again. - The
allow-admin: falsewarning 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,.apkand.ipkpackages now declare the FUSE helper (fuse3, orfuse-utilson OpenWrt). On RPM hosts it is a recommendation, so an EL7-class host still installs and runs without a shared drive. - On OpenWrt,
install.shnow installskmod-fuseandfuse-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/nobgpcould 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_directorynow reportsoffline_atfor 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_atis also returned withbrief: 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_pininnobgp statusis 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
nobgpvolumes 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
nobgpdrives 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 retryableinternal. Retry withadmin: true. - An auto-upgrade on slow hardware no longer logs
auto-upgrade failedafter 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 retryableinternal. - 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 retryableinternal. - 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 withadmin: false. They no longer refuse. See A second identity on Windows. allow-admin: falseon 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 uninstallkeeps it. That account has no network credentials, so a command that reads a file share needsadmin: true.
Security
- ⚠ On 0.4.44 and 0.4.45, on a Windows node whose
userwas an administrator, an unelevatedfs_readcould read files that the account had no permission to read. This no longer happens. Other nodes were not affected.
Other changes
network_directorynow shows whether the unelevated account is an administrator (info.user_is_admin, router 0.4.47).nobgp statusshowsunelevated_is_admin. Absent is notfalse.- 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_directorynow returnsinfo.user_is_admin. When it istrue,admin: falseruns as an administrator on that node. It has three states, and absent is notfalse.- The
adminguidance 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_nodeandnetwork_delete. - A
network_idnow 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_directorynow shows the machine model asinfo.hardware_model, for exampleDS918+orMacmini9,1. It can be empty on a VM, a container or an older agent.fs_write,fileop=writeandop=fetch_urlnow create missing parent folders. You no longer needfs_mkdirfirst.- The new folders belong to the identity that
adminselects.allow-rootsstill applies.
Agent 0.4.44 — August 2026
Execution identity
- A configured
usernow gives a Windows node its second identity. Thewindows-user-identitykey 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.
commandand terminal sessions still refuse an unelevated call. nobgp config --user <account>now works on Windows.network_directoryshows the account.
Provisioning
- A provisioned node now accepts
admin: falsefrom its first boot. NOBGP_USERnow also works on an installed agent, and overrides the config file. See Environment Variables.nobgp config --usertells you whenNOBGP_USERoverrides 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_nodenow tells you how to wait for the new node, and returnsnetwork_nameand the normalizednode_name. It still returns nonode_id.resource_summarynow shows the CPU and memory actually allocated.deprovision_nodenow succeeds on a task that is already stopped.
Directory and services
- A filtered
network_directoryno longer returns networks with no matching node. A network you name withnetwork_nameis still returned. - Brace expansion in a glob, such as
{web,db}*, now returnsinvalid_argsinstead of zero nodes. service_publishnow 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_*andfilecalls withadmin: falseas a configured account. Setwindows-user-identity: trueand auser. No password is stored. The key is off by default. See A second identity on Windows. - On such a node, an unelevated
commandor terminal session returnsfailed_precondition. Sendadmin: true. nobgp config --user <account>works on Windows when the key is on. A Windows install records the signed-in desktop account inuser.network_directoryshows 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
nobgp statusnow shows which account anadmin: falsecall runs as (unelevated), or why none can (unelevated_refusal). See The fourth line is not a veto.- The local
statustool returns the same block for that node.network_directoryis not on the local MCP surface. - The local MCP server now explains at connect time which identity a call gets. See Which identity a call gets, from here.
Router 0.4.43 — August 2026
whoaminow returnscan_elevate. When it isfalse, everyadmin: truecall returnsforbidden. A node withallow-admin: falsestill refuses. See two gates.whoamialso returnsorgs[], with your role andcan_elevatefor each organization. If your roles differ, there is no top-levelcan_elevate.network_directorynow returnsorg_idon each network, to matchorgs[].- Send
admin: truefor 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: falsewhen that call would run as root (uid 0). This includes a service install with nouser, a bare-root container, every Windows node, a deleteduser, anduser: root. The refusal isfailed_precondition. See Unelevated never means root. - ⚠ To serve unelevated calls, run
sudo nobgp config --user <account>, or sendadmin: true. - An agent that already runs unprivileged still serves
admin: false. nobgp config --user rootis now refused.--allow-admin=falsenow reports the node's actual case.network_directoryinfo.useris 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: falseas uid 0 asfailed_precondition(not retryable). To fix it, configure an account (sudo nobgp config --user deploy) or retry withadmin: 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_directoryinfo.usernow 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 arecursivefs_listor a very largefs_glob. Narrowpathor droprecursive, becauselimitandoffsetdo 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_filesis 0.
Router 0.4.41 — August 2026
fs_grepnow returnsskipped_files, the count of files over the 16 MiB limit that it did not read.fs_grep_subscribereports it in each completion event.- ⚠ Check
skipped_filesbefore you trust a zero. An agent below 0.4.40 always reports0.
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_nodeandnode_label. A Member keeps all operational actions: nodes, services,commandand the file tools. See Roles & Permissions. - ⚠ Only an Owner or Admin can now turn off a service's authentication (
auth_required: false) onservice_publishorservice_update, or runnode_label. A Member getsforbidden(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_emailsneed no extra role.
Agent 0.4.39 — August 2026
- File walks (
fs_list,fs_glob,fs_grep,fs_statand thefileops) now report results under the path you sent, not under the resolved symlink target.fs_statof a link describes the link again. - A walk now starts at the same path that the
allow-rootscheck 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_greporfs_grep_subscribepattern that is not valid RE2 now returnsinvalid_args(HTTP 400). Before, it returned a retryableinternal. - 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_foundortoo_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 returnstoo_large, notinternal. - macOS: a recursive walk of
/tmp,/etcor/varnow 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 example143forSIGTERM. Windows still reports1. - Windows: quotes now reach
cmd.exeunchanged, 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 retryableinternal. This coversallow-admin: false, a path outsideallow-roots, a domain removed fromallow-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 returnsfailed_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 amanagegrant) and the node'sallow-admin. See Node Access Control. - The agent's configuration directory stays refused at both identities.
- On Windows,
allow-rootsstill applies to unelevated file calls.
File search and containment
- ⚠
fs_grepandfs_grep_subscribenow work. On older agents they fail withpath must be absolute: "". Upgrade the agent to use them. fs_grepnow checks every entry inpathsagainstallow-roots.- A recursive
fs_list,fs_globorfs_grepno longer lists or reads the files in the agent's own directory. fs_globwithfollow_symlinksno longer reports targets outsideallow-roots.- On a node with a configured
user, walks now apply the owner'sallow-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: truenow needs an org Owner or Admin. A Member getsforbidden. Retry withoutadminto run as the node's configured account. See Execution identity. - On a node's local MCP server, the node's grant decides:
managecan elevate on peers,observecannot. - An elevated
command_subscribeis refused for the whole cohort or runs on all of it. - The
fs_*tools now acceptadmin.fs_grep_subscribedoes 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_grepover MCP to search a node's files with an RE2 regex. ⚠ It needs agent 0.4.37 or later. - Send a
progressTokento get each match as a progress notification. Without one, the response holds all hits inmatches[]. Readcountto know if the search found anything. fs_grepalso works on a node's local server at theobservetier. There it always returns the full result.- New tool:
fs_grep_subscribesearches a whole cohort through the event bus. Read matches withevent_tail.outstanding: 0means the search is complete. See Searching a fleet. event_subscriptionsnow reports thegrepkind.
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_grepworks again on nodes with a configureduser. There, matches arrive when the search finishes.
Agent 0.4.34 — July 2026
Execution identity
- ⚠ This agent release makes
adminwork oncommand,command_subscribe,fileand terminals. On an older agent,admin: trueruns 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 clearuser.
Node access control
- The file tools and fs watches never serve the agent's own directory, for example
/etc/nobgp.allow-rootsandadmin: truedo not open it. See Node Access Control. - ⚠
allow-admin: falsenow refuses all work that runs as uid 0. On a node where the agent oruseris root, remote execution stops on upgrade. Set an account withsudo nobgp config --user=<account>first. - Windows:
allow-admin: falsenow also refuses file operations. - The
nobgp configwarning andallow.warninginnobgp statusnow say that terminal services are refused too.
Router 0.4.33 — July 2026
- ⚠
adminreplacesusernameoncommand,command_subscribe,service_publishandservice_update.false(default) runs as the node's configured account.trueruns as the node's ambient identity. A call withusernamereturnsinvalid_args. Replaceusername: "root"withadmin: true, and remove the field in all other calls. See Execution identity. - To run as another account, use
suorrunasin the command. filenow takesadmin, and file operations run as the chosen identity. Usefilefor elevated file operations.- A terminal published with
username: "root"now hasadmin: true. A terminal with another account now runs as the node's configured user. To elevate it, setadmin: truewithservice_update. network_directorynow showsuserandallow_adminfor each node. An emptyusermeansadmin: falseruns as root.
Agent 0.4.33 — July 2026
- ⚠
allow-toolsandallow-adminnow also apply to published terminal services. Plan on-device access before you restrict a node behind CGNAT. See Node Access Control. - ⚠ Windows:
allow-admin: falsenow refuses all remote execution on the node. nobgp confignow refuses a--useraccount that does not exist, and refuses--useron Windows.--allow-admin=falsenow tells you its effect, and asks for confirmation when it turns off remote execution.- The
--userhelp text is corrected.--useris the default account for commands and file operations. See the CLI reference.
Router 0.4.32 — July 2026
username: "root"now requests elevation, andadminis removed fromcommandandcommand_subscribe. A call withadminreturnsinvalid_args. Replaceadmin: truewithusername: "root". See Execution identity.- Opening an API host in a browser now goes to the docs, for example
mcp.nobgp.comgoes to the MCP section. MCP clients and API callers do not change.
Agent 0.4.32 — July 2026
nobgp service logsnow needs root and shows all agent logs. On Linux and macOS it runs itself withsudo. 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
statustool. nobgp listnow reports an unreadable profile directory, notNo profiles found.
Agent 0.4.31 — July 2026
Installation
brew install nobgp/tap/nobgpworks again on macOS. Run the install command again.- ⚠ The
latestdownload 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 statusnow shows TLS interception inrouter.tls_intercepted, and other VPNs and security products in anenvironmentblock.- 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 statusno 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-rootsentry 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.cmdinstaller is removed. Use the one-line installer in any Windows shell. - RPM-based installs now use
dnfwhen 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-toolssets which domains (fs,command) the node serves. It replacesevent-sources, and existing values migrate.allow-rootssets which roots thefstools and watches can use. It replacesevent-watch-roots.allow-adminsets whether work can run as root or Administrator. On Windows,allow-admin: falseis refused at startup.- All three are permissive by default and show in
nobgp showandnobgp status. See Node Access Control.
Commands and event bus
commandandcommand_subscribenow takeadminorusername.- ⚠
command_subscribenow runs as the node's configured user, not root. Addadmin: trueif 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.
archselectors acceptarm64/aarch64andamd64/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_tailno longer loses events. - You can use a node name without a network name when it is unambiguous.
fs_statacceptsallow_missing, andfs_deleteacceptsforce.whoamino longer returns an empty email for calls through a node.nobgp showno longer printsallow-*settings twice or shows an oldquic-routervalue.- 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.