Skip to main content

Changelog

Notable user-facing changes to the noBGP router and agent. Router and agent are versioned independently — a router version and an agent version that share a number are unrelated.


Agent 0.4.36 — July 2026

Configuration file

  • An upgraded node now tidies its config file on the first restart. 0.4.35 changed the file to record choices rather than defaults, but only rewrote it the next time the agent had something of its own to record — the mount point, a learned QUIC value, the local MCP port. On a settled node none of those fire again, so a node upgraded to 0.4.35 kept its pre-upgrade file: every default still frozen in as an explicit setting, retired keys still present. The agent sweeps the file when it starts now. No effective setting changes either way. See Configuration File.
  • The file is touched only when its contents would differ. A rewrite that would produce the same bytes is skipped, so on a node whose config is already correct — the usual case once it has been swept — startup changes nothing, not even the file's timestamp. Removing retired keys is atomic too, closing the same truncate-then-write window 0.4.35 closed for the main write path.

Router 0.4.35 — July 2026

  • fs_grep is on MCP. It had been reachable only over REST — registered, working, and in no client's tool list. AI clients can now search a node's files with an RE2 regex directly. Reconnect your MCP client after the upgrade so it picks the tool up.
  • Results arrive one of two ways, and you choose. Send no progressToken and the response carries every hit in matches[]. Send one — which is how a client declares it consumes notifications — and each match arrives as a notifications/progress message as the walk finds it, with the response setting streamed_as_progress: true and omitting matches[] rather than sending everything twice. Either way count, scanned_files, truncated and duration_ms are populated, so read count, not the length of matches, to know whether a search found anything. See fs_grep.
  • fs_grep works from a node's own local server too, at the observe tier, where it is always synchronous: that endpoint has no channel for a mid-call push, so it ignores a progressToken and returns the complete result — the same thing a caller that sent no token gets. The two surfaces differ by authority, never by transport.

Event bus

  • New tool: fs_grep_subscribe — the same RE2 walk across a whole cohort, delivered through the event bus instead of one big response. It returns immediately with a subscription_id; matches arrive as events attributed by source_id to the node each one is on, read with event_tail and ended with event_unsubscribe. Like a command dispatch it always ends: every node reports once, and outstanding: 0 in event_tail's progress block means the search is complete. Available at the observe tier on a node's own server, and the only way to read search results incrementally there. See Searching a fleet.
  • event_subscriptions now reports grep as a fourth subscription kind, alongside fs, command and presence.

Agent 0.4.35 — July 2026

Configuration file

  • The config file records choices, not defaults. A key is written only when its value differs from the default; everything else appears as a commented # key: value line under a short block explaining that uncommenting one pins it. Older agents froze every default into the file the first time nobgp config ran, so a node carried explicit values nobody chose — and a later change of default could never reach it. A 0.4.35 agent tidies that on its next write, with no change to any effective setting. The file is agent-generated: hand-written comments do not survive a rewrite, and keys the agent no longer reads are swept out with a note naming their successor (event-sourcesallow-tools, event-watch-rootsallow-roots). See Configuration File.
  • The file is replaced atomically. It now holds things a node cannot re-derive — the overlay slice, the local MCP port and token, the learned QUIC endpoint — and the old write truncated before it wrote. An upgrade restart or a power cut inside that window brought the node back without them, re-minting an MCP token every nobgp mcp install registration had frozen into a client config, and re-picking an overlay slice.

File search

  • fs_grep works again on nodes with a configured user. Agent 0.4.34 moved file work onto a privilege-dropped worker and refused the incremental (streaming) form of fs_grep there, which is most nodes — registration sets user to the installing account. The call now falls back to returning the whole result in one response instead of being refused; the only difference from a search that runs as the node's own identity is that matches arrive when the walk finishes rather than as they are found.

Agent 0.4.34 — July 2026

Execution identity

  • This is the agent release that implements the two identities. The admin flag on command, command_subscribe, file and published terminals shipped router-side in 0.4.33; a node has to be on agent 0.4.34 for it to mean anything. An older agent ignores it and runs the work as its configured user — so admin: true against a node you have not upgraded does not elevate, it just fails to. The skew is safe in both directions: neither side ever elevates on its own.
  • File operations really do drop privilege now. The agent changes identity before it opens the file, so ownership and permissions are the ones that account would get, and the atomic rename that finalises a write is checked against it too — a caller cannot create bytes as one account and land them somewhere only another could write. Until this release the file tools ran as the agent itself and merely checked whether the account could have done it, which is why a path readable through fs_read could be denied through command on the same node.
  • An agent that is not running as root cannot act as user. Assuming another account is a superuser privilege. On a node where the agent runs unprivileged — a foreground nobgp agent started by an ordinary user — a file operation that would run as user is now refused, naming the reason, instead of running as the agent's own account. Either run the agent as root or clear user. Command sessions already behaved this way, and service installs are unaffected.

Node access control

  • The file tools never serve the agent's own directory. Every path inside /etc/nobgp (/usr/local/etc/nobgp on macOS, C:\ProgramData\nobgp on Windows) is refused to the fs tools and fs watches, with symlinks resolved first. No allow-roots value opens it and neither does admin: true. That directory holds the node's network key, its JWT and the config the capability keys are read from — with the permissive defaults, all of it was one fs_read away, and a caller holding fs could edit away the veto meant to confine it. command is unchanged: a session running as an account that can read those files still can. See Node Access Control.
  • allow-admin: false now refuses the two cases it always claimed to. The setting is documented as refusing anything that resolves to uid 0, but a request that asked for no particular privilege was still served as root on the nodes where that is the fallback — a container, a bare-root install — and so was work on a node whose configured user is itself a superuser account. Both are refused now. If you have such a node carrying allow-admin: false, remote execution on it stops working on upgrade, which is what the setting has been describing all along; give the veto somewhere to land with sudo nobgp config --user=<account> first.
  • Windows: allow-admin: false now covers file operations too. Since 0.4.33 it refused commands and terminal sessions there, but every file operation was still served as LocalSystem. It is one answer for all of them now.
  • The lockout warnings say what is actually true. The nobgp config warning and the allow.warning field in nobgp status used to claim a published terminal service was unaffected by these keys. It has not been since 0.4.33; both now state plainly that terminal services are refused along with the tools and that the way back in is on-device.

Router 0.4.33 — July 2026

Command execution

  • One boolean now decides who work runs as. username is gone from command, command_subscribe, service_publish and service_update, replaced by admin: a node offers exactly two identities and this picks between them. Omitted or false runs as the account the node's owner configured; true runs as the node's ambient identity, which a node set to allow-admin: false refuses rather than downgrades. Calls that still pass username are rejected with invalid_args — replace username: "root" with admin: true, and drop the field everywhere else. Reconnect your MCP client after the upgrade so it refetches the schemas. See Execution identity.
  • Why the account name went away. It never meant one thing: root could be a spelling or a user id, and on Windows the agent ignored the name entirely and ran as LocalSystem — so a session asking for another account had never once run as it. Two identities is also what makes Windows parity reachable. To run as some third account, use su or runas inside the command itself.
  • File operations now run as that identity too, and file takes admin. The agent drops privilege before opening the file, so ownership and permissions are the ones that account would get — a file written with admin: false is owned by the node's configured user, not by root. Previously the file tools always ran as the agent's own account, which is why a path readable through fs_read could be denied through command on the same node. The per-op fs_* tools carry no admin and always act as the configured user; use file when an operation needs elevation.

Published terminals

  • Terminal services that named an account have moved to one of the two identities. A terminal published with username: "root" now carries admin: true and behaves exactly as before. Every other named account now runs as its node's configured user — less privileged than what it asked for, which is the safe direction, and on Windows the direction it was already running in. Terminals that named no account are unaffected. If one of yours needs elevation, set admin: true with service_update.

Discovery

  • network_directory reports what admin will mean on each node. Each node's info block now carries user — the account unelevated work runs as, empty when none is configured, which is the case worth noticing because admin: false then resolves to root — and allow_admin, false when the node's owner refused elevation outright. Both are set on the node only, and both are absent on agents too old to report them; absent is not the same claim as empty or false. See network_directory.

Agent 0.4.33 — July 2026

Node access control

  • A node's capability settings now govern published terminal services too. allow-tools and allow-admin previously bounded only the MCP tools and event-bus sources; a terminal service published to run as root therefore handed out root on a node whose owner had set allow-admin: false. One rule applies to every execution surface now: a node that no longer serves the command domain refuses the browser terminal, and an elevated terminal is refused rather than quietly run as another account. If you narrow a node behind CGNAT, plan for on-device access first — see Node Access Control.
  • allow-admin: false is honoured on Windows. Windows has no unprivileged identity to drop to, so earlier agents logged that they could not apply the setting and kept admin enabled. It is now honoured as the only answer the platform can give: remote execution on that node is refused entirely. Existing Windows nodes carrying allow-admin: false in their config will stop serving remote execution on upgrade.
  • nobgp config checks the two identity settings before it writes them. --user naming an account that does not exist is refused at the point of setting, instead of failing at every session later; on Windows --user is refused outright, since there is nothing to switch to. --allow-admin=false says what it costs — with a user configured it states that sessions will run as that account, and where it turns remote execution off entirely it asks for confirmation (a scripted run proceeds with a warning in the log).
  • The --user help text said the opposite of what the agent does. It described --user as a restriction that only applies under allow-admin: false. It is the default account for command sessions, dispatched bus commands and file operations whenever the caller names none — registration sets it to the installing account, so an ordinary sudo install has never run sessions as root. allow-admin: false additionally pins work to it. The CLI reference has the corrected description.

Two user-facing messages shipped in this release still describing the old scope — the nobgp config warning and the allow.warning field in nobgp status both said a published terminal service was unaffected. Corrected in agent 0.4.34; on 0.4.33 treat on-device access as the way back.


Router 0.4.32 — July 2026

Command execution

  • One field now decides who a command runs as. The admin option is gone from command and command_subscribe; naming the superuser (username: "root") is how you ask for elevation. The pair existed because "Administrator is not a user" on Windows — a distinction the agent already enforces by refusing a username there outright, so it did not need to reach every caller. Calls that still pass admin are rejected with invalid_args — replace admin: true with username: "root". Everything else is unchanged: the default is still the node's configured user (not root), and allow-admin: false still refuses an elevated request rather than downgrading it. See Execution identity.

Landing pages

  • Opening an API host in a browser now lands on the documentation instead of a 404. https://mcp.nobgp.com/mcp — an MCP endpoint, not a web page — sends a browser to the MCP section, as does the bare mcp.nobgp.com; other API hosts send it to the docs home. Only requests that ask for HTML are redirected, so MCP clients and API callers are untouched.

Agent 0.4.32 — July 2026

Command-line privileges

  • nobgp service logs now requires root, like the rest of nobgp service. Run unprivileged, it asked the systemd journal for logs as the calling user — which returns only that user's own messages, so the agent's lines were missing with nothing to say they were missing rather than absent. On Linux and macOS the command re-executes itself under sudo; on Windows run it from an Administrator terminal. The full rule, and which commands need root, is now written down in Root privileges.
  • Windows privilege refusals now say what to do. Commands that need Administrator rights on Windows do not self-elevate — a console cannot raise its own privileges, and a UAC re-launch would move the output and the exit code to another window. The refusal now names the exact command to repeat from an Administrator terminal and points at the local MCP server's status tool for read-only state without privileges. Windows installs are unchanged: the installer still requests UAC elevation for you.
  • nobgp list no longer reports a configured node as having no profiles. When the profile directory cannot be read, the command now fails naming the directory and the reason instead of printing No profiles found.

Agent 0.4.31 — July 2026

Installation

  • Fixed: brew install nobgp/tap/nobgp failed on macOS. The formula pointed at a download path that is no longer published, so every Homebrew install failed to fetch the binary. Re-run the install command — nothing needs cleaning up first. Installs through the install script were unaffected.
  • The floating latest download path is retired. Every installer and nobgp upgrade already resolves the version to install from the router's release channel, so nothing changes for a current agent. Agents older than 0.3.80 used the retired path for manual upgrades and will now fail with a download error — reinstall those hosts with the install script.

Diagnosing interference from other software

  • Certificate errors now name what caused them. When antivirus HTTPS scanning or a corporate proxy re-signs a connection, the install scripts and the agent report the certificate's owner — products identify themselves there — and point at the new Security software and VPNs guide, instead of failing with a bare validation error.
  • nobgp status reports interference it can see from the box. router.tls_intercepted names anything re-signing the control channel, and a new environment block lists other products' active VPN adapters (tunnels) and third-party antivirus/firewall software (security_products). Both are deviation-only: on a clean machine nothing is added to the output.

Fixes

  • Windows: the network drive no longer disconnects and remaps every 30 seconds. Drive mappings belong to the logon session that created them, so the agent's health check could not see its own mapping once it moved into the desktop session and tore down a perfectly healthy mount, over and over. The check now runs in the session that owns the mapping, and fs.mounted in nobgp status reports the real state.
  • Linux: applications with strict DNS resolvers no longer fail on public names. On hosts where the agent has to sit as the first nameserver in /etc/resolv.conf, non-overlay lookups are now forwarded to the machine's own nameservers instead of being refused. Resolvers that treat a refusal as fatal (Node.js, Bun) could not resolve anything on those hosts. See DNS & hostname resolution.
  • Fewer false alarms in the new environment diagnostics. A DSL or mobile-broadband uplink and the Windows Teredo/ISATAP pseudo-adapters are no longer reported as third-party tunnels, and nobgp status no longer waits on the operating system's security-product query, which could stall the whole command on an unhealthy Windows host.

Router 0.4.31 — July 2026

Reliability

  • A single message the router can't act on no longer drops a node's control channel. A malformed request, or a message type a newer agent sends that an older router doesn't handle yet, is now logged and skipped instead of ending the connection. Only a channel that genuinely can't do its job — a read failure, or a write the router can't complete — disconnects a node.
  • Router-side disconnects are no longer shaped like credential rejections. When the router closes a connection for an operational reason, the agent receives it as a normal close that still carries the reason into the agent's local log, so a routine disconnect can't be misread as a deleted node or a revoked key and stop the agent from reconnecting. Genuine rejections — revoked credentials, an unsupported agent version, and the duplicate-instance flap guard — are unchanged and still reported as rejections.

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

Node access control

  • Fixed: a whole-filesystem allow-roots entry matched nothing on Windows.
  • Node grants no longer carry an expiry — a grant stands until it is revoked.

Installation

  • Fixed: the Windows installer failed before downloading anything. Any install that didn't pin NOBGP_VERSION stopped while looking up the version to install, after printing the banner and the detected architecture. Re-run the one-line installer — no cleanup needed.
  • One published command, every shell. The single powershell -NoProfile -Command "irm ... | iex" line is the only Windows installer; it runs as-is in Command Prompt, PowerShell 5.1 and PowerShell 7. The separate install.cmd variant is retired — update any bookmarked command that still points at it.
  • RPM-based installs now prefer dnf when available.

Reliability

  • Fixed: one offline peer could disrupt other nodes' control channels on the same router.

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

Node access control

Three settings let a node's owner narrow what the node serves remotely, enforced on the box itself. See Node Access Control for the full model.

  • allow-tools — which capability domains the node serves (fs, command). Replaces the earlier event-sources key, which governed only the event bus; the new setting governs the MCP file and command tools as well, so one answer covers every programmatic caller. Existing event-sources values are migrated automatically, and the migration can only preserve or widen access — never narrow it.
  • allow-roots — which filesystem roots the fs tools and fs event source may touch. Replaces event-watch-roots, with the same migration behavior.
  • allow-admin (new) — whether work may run as root / Administrator. When false, execution drops to the account named by --user, and an explicit request for root is refused rather than silently downgraded. On Windows, where the service runs as LocalSystem with no unprivileged account configured, allow-admin: false is refused at startup with an error and admin stays enabled — use the router-side node grant to restrict access instead.

All three default permissive, and all three appear in nobgp show and nobgp status.

Scope, stated plainly: these settings govern the programmatic surface — the MCP tools your assistant calls and the event-bus sources the router dispatches. They do not govern a published terminal service, whose command and user are fixed when you publish it. That exemption is deliberate: it keeps a locked-down node recoverable through its terminal instead of requiring physical access.

Command execution

  • Choosing who commands run as. command and command_subscribe now take the same pair of options: admin (run elevated — root on Unix, the service's Administrator context on Windows) and username (a specific account, Unix only). Setting both is an error.
  • Fleet dispatches no longer run as root by default. command_subscribe previously ran every dispatched command as root with no way to choose otherwise; it now defaults to the node's configured user, matching the single-node command tool. If you rely on dispatched commands having root, add admin: true.
  • nobgp notify works from dispatched commands. Scripts run by the event bus can call nobgp notify directly — the agent's directory is on their PATH, and the local API socket is reachable by the account those commands run as.

Event bus

  • Overflow says which side overflowed. When a node's buffer or the kernel's event queue fills, the terminal overflow event now carries a reason instead of only a status.
  • Subscriptions report the nodes they matched. Every subscribe call returns the resolved node list, not just a count — so you can see what a selector actually matched without creating a throwaway subscription.
  • A zero-match selector says so rather than returning a success-shaped empty result.
  • arch selectors accept either spelling. arm64/aarch64 and amd64/x86_64 now mean the same thing; previously the value shown everywhere else in the product matched nothing here.
  • Command results always carry exit_code, including zero. Previously a clean exit reported no exit code at all, which was indistinguishable from "still running".

Tools and reliability

  • Fixed: array and number arguments were rejected from some clients. Tools taking lists (node_names, watches) or numbers (idle_timeout) could not be called from Claude Code. Reconnect your MCP client to pick up the corrected schemas.
  • Fixed: reading events could lose them. A failed event_tail response discarded the batch it could not deliver; the events are now restored and redelivered on retry.
  • Node references are easier. Tools accept a node name without a network name when the network is unambiguous, and status / resolve now return node IDs — so there is a path from a name you know to the ID the tools take.
  • fs_stat accepts allow_missing and fs_delete accepts force, matching the file tool they project.
  • Clearer errors. Your command output no longer appears in noBGP's server logs; nobgp notify distinguishes a permission problem from a stopped agent; failed writes name the file you asked for rather than a temporary one.
  • nobgp show corrected. The allow-* settings printed twice in two different formats, and a quic-router value left behind by older versions was displayed as though it were an active override — it is ignored by the agent, and the line contradicted the endpoint reported directly beneath it. Both fixed; nobgp status was unaffected.
  • whoami no longer reports an empty email for calls arriving through a node — the field is simply absent there, with node_context identifying the node. Reconnect your MCP client after upgrading the router, or it will reject the new response shape until it refetches.

Documented behavior worth knowing

  • Filesystem events differ by platform. On macOS, event paths come back with symlinks resolved (/tmp/x reports as /private/tmp/x), and a file created then immediately written may report only the create. Linux reports distinct operations on unresolved paths.
  • Commands run through the login shell on Unix (bash, sh or zsh depending on the host), not a fixed sh.
  • File tools and command tools may run as different users on the same node, so a file readable through fs_read is not necessarily readable through command.

Platform fixes

  • macOS: fixed service installation, which could leave a freshly installed agent without a running service.
  • Windows: installer now forwards all NOBGP_* environment variables when elevating; file replacement retries when the target is briefly open.
  • Linux: install.sh works on headless hosts and quotes its environment passthrough correctly.
  • Upgrades: an unpublished version now says so instead of reporting a permissions error, and the download is checked before you are prompted.