BrowserAI 1.0.0
BrowserAI is a Windows MCP server that gives an AI agent a real browser, either Chromium or Firefox. It carries its own copy of everything it needs, so there is nothing else to install.
This is the first version fit for real use. It replaces the build of the same number published on 2026-08-17. That build was downloadable for a month. Nobody is known to have installed it apart from the maintainer, and it did not exit when it had nobody left to serve.
There are two programs in the release. BrowserAI.Server.exe is the MCP server your client starts. BrowserAI.exe is a small configuration app. It opens when the install finishes, and it registers the server with your client.
Read README.md first.
Added
- ✨ BrowserAI ships as two executables from this release. read more
- ✨
BrowserAI.exeis the configuration app, and it opens after the install. read more - ✨ The two registration scopes are offered in OutlookAI's own words. read more
- ✨
BrowserAI.exe --report <path>writes a JSON status report and exits. read more - ♻️
BrowserAI.Coreis the library both executables share. read more - ✨
Runtime/PeSubsystemreads a binary's subsystem out of its own PE headers. read more - ✅
RealInstallerTests.TheInstalledMainExecutableOpensOneDialogAndNoConsoleWindowis new. read more - ✅
ConfigurationAppTestscovers the configuration app. read more - ✅
HouseRuleTests.EveryArmInAFileThatOverridesTheEnvironmentRunsBesideNothingis new. read more - ✅ The corpus every tree-as-text rule reads is now asserted against
git ls-files, in both directions. read more - ✅
SaturationTests' torn-record arm is scoped to the run's own pids. read more - 📝 The
--treenode-filtertrap, inkb/toolchain.md. read more - 📝 The 2026-08-24 adversarial review is a dated record rather than a file in
.work\. read more - ✅ Every run says whether it could have seen a browser take the foreground. read more
- 📝 The server
instructionsnow say what a full-page screenshot costs, before a model reaches for one. read more - ✅ The dated records are append-only, and a test says so. read more
- ✨ Six per-run arguments, and four opinions that stopped being arguments. read more
- ✨
browserai_catch_up, the seventh authored tool. read more - ✨ One time-ordered log, inside
browserai.json. read more - ✨ A required
whyon every call that names a session. read more - ✨ Ten tools, reachable for the first time in this product's history or its predecessor's. read more
- 📝 A warning in the server
instructionsthat response mocking can make a page lie to a human. read more - ✨
browserai_listnow says whether each session it reports is being driven, three-valued. read more - ✨ Liveness is three-valued:
Alone,NotAlone(n)orUndetermined(why). read more - 🔒 A reinstall takes the machine's browsers root for the whole call. read more
- 🔒 The family reinstall's session gate is now unconditional. read more
- 📝
--storage-statetogether with--user-data-diris a silent no-op. read more - 📝
--capsaccepts any word at all. read more - 📝 Two browsers on one profile directory: Chromium refuses and Firefox hangs. read more
- 📝 The user agent is settable from the config on both families. read more
- 📝 Firefox is owed Chromium's rename measurement, and now has it. read more
- 📝 The CsWin32 metadata licence terms are in the repository, quoted verbatim. read more
- ✨
browserai_reinstall_browsergained a third value,shared. read more - ✨ Firefox is a browser you can ask for. read more
- ✅ A budget gate over every model-facing string, measured off the wire. read more
- ✅
RecordedCountTests, which generalises the one place counting discipline was mechanised. read more - 🐛 The per-directory session gate refused sessions that nothing was wrong with. read more
- ✅ The suite's torn-log check had never matched a log record. read more
- ✅ A test asserted a durable property on a channel that is not durable. read more
- ✅ Five product source files were outside every scan built on the repository walk. read more
- ✅ A test asserted that the developer's screen was busy. read more
- 🐛 A session another BrowserAI was writing to could not be opened. read more
- 🐛 A child that took longer than sixty seconds to start was reported as a protocol failure. read more
- 🐛
browserai_reinstall_browsercould delete the browser tree and wait an hour. read more - ✅ Both intermittent failures now name their own state. read more
- ✅ CI's four skipped tests are settled rather than rediscovered. read more
- ✅ The build runs on a machine nobody owns. read more
- ✅ The
#anchorhalf of every relative link is checked too. read more - 📝
Interop\,Sessions\andRuntime\have working instructions of their own. read more - ✨ BrowserAI registers itself with your MCP client when it installs, and unregisters when it goes. read more
- 📦 A registration that could not happen says so, and never breaks the install. read more
- 📦 Installing, updating, repairing and reinstalling all leave exactly one registration. read more
- 📦 The version comes from the git tag and is typed nowhere. read more
- 📦 A build that cannot work out what version it is now fails. read more
- 📝 This changelog. read more
- ✨ The running build's version is the first line of every process log. read more
- 📦 Silent background self-update, per-user, with a rollback that works. read more
- 📦 An update is never applied while another BrowserAI is running. read more
- 📦 Rollback is publishable as well as acceptable. read more
- 📦
build/New-Release.ps1builds a release end to end. read more - 📦 Velopack's MIT licence and a trademark disclaimer now ship inside the package. read more
- 📦 A release now records the resolved set beside its artifact. read more
- 📦 BrowserAI has an icon, and it is candidate 3 of the ten drawn on 2026-09-15. read more
- ✅ Every asset reference in the prose resolves, and the exclusion hiding them is narrowed. read more
- ✅ The shipped icon's shape is a gate, and its planted red is a doctored file. read more
- ✅ Nothing in a release body may carry a character a person would not type. read more
- 📝 Setup asks before installing over an existing install, and says
Repairon a re-ship. read more - ✨ Every file a tool result names is now named absolutely. read more
- ✨
browser_emulate_mediaarrives and is allowed. read more - 📝 The gate now says to publish the slice again after a
src/change. read more - 📝 The disk total after a first run is stamped stale rather than left reading as current. read more
Changed
- 📦 A pack built for the gate is not a release, so it is not given a release body. read more
- ✅ An empty
[Unreleased]is legal while a release is being cut, not only once it is tagged. read more - 📦 The GitHub release body is generated from the section rather than cut out of it. read more
- 📝 Every entry in this changelog is an icon, a one-sentence headline and a fold. read more
- 📦 The production-feed check reads the body, because a 200 was measured carrying the wrong one. read more
- 📝
RELEASING.md: moving a tag does not draft the release; deleting one does. read more - 📝
TESTING.mdsays to wait for.work\test-scratchto clear between two suite runs. read more - ✅ A suite race the packed release let loose reddened arms that did not hold the variable. read more
- ✅ The same race had a second face, it passed, and nothing would have said so. read more
- ✅ Both halves of the race fix were watched against a live reproduction of it. read more
- 💥 The MCP server is
BrowserAI.Server.exe, and older registrations name a file that is gone. read more - 🔧
RegistrationTargetcomposes the server's path instead of copying its own. read more - 🔧 The configuration app clears
VELOPACK_FIRSTRUNandVELOPACK_RESTARTfrom its environment. read more - 🔧 The configuration app is a member of the live-instance census for as long as its window is open. read more
- 📦
build/New-Release.ps1publishes both projects into one pack directory. read more - 📦
--shortcuts StartMenuRoot, corrected fromNone. read more - 📦
assets/BrowserAI.icois wired into the pack and into both executables. read more - ✅
ChangelogTestswas red on every release commit, and the check was what was wrong. read more - 📝
RELEASING.mdstates the order of the last six steps. read more - 📝
README.md's test-count sentence, re-measured with a release pack present. read more - 📝 Three documents said this product had never been distributed, and it had been. read more
- 🔒 One of the two WebMCP tools upstream added is refused, and the other is not. read more
- ⬆️
@playwright/mcp0.0.81 andplaywright-core1.64.0-alpha-2026-09-14 adopted. read more - 🔧 The generated child config now writes
timeouts.idleexplicitly. read more - 🔒 BrowserAI refuses to start when its install root is outside your Windows profile. read more
- 📦 The release downloads are called
BrowserAI.exeandBrowserAI.zip. read more - 📦 BrowserAI's data moved out of the install directory, and the installer's own name changed with it. read more
- 📦 Uninstalling now asks whether to delete your data, and keeps it by default. read more
- 🔧 BrowserAI no longer keeps running when the installer starts it. read more
- 💥 Every machine re-provisions its browser on first run after this. read more
- ⬆️
@playwright/mcp0.0.80,playwright-core1.63.0-alpha-2026-08-31 and Node v24.21.0 adopted. read more - ⬆️ Upstream now honours
chromiumSandboxfrom a config file. read more - ⬆️ Every source and test project re-resolved. read more
- ✅ Every run now states the publish freshness it established, instead of only refusing when it did not. read more
- 📝 The six-run-gate hazard closed on the condition it wrote for itself. read more
- ✅ A stale-publish alarm was a commit date read as a file timestamp. read more
- ✅ A hazard row the parser could not read left both tallies in the same instant, and nothing said so. read more
- ✅ The failure dump could not read the files it exists to inline. read more
- 📝 The six-run-gate hazard row is
openagain, on the condition it wrote for itself. read more - 🔧 A process re-taking a session directory it last held now says so. read more
- ✅ The suite's coverage block records the machine's commit charge. read more
- ✅ The browser-containment driver reads its child's
stderrinstead of buffering it. read more - ✅ A payload that re-resolved makes the published binary stale. read more
- 📝 The silent Chromium death was reproduced on purpose, and desktop heap is the cause. read more
- 📦 The release manifest says whether the release was a crunch override. read more
- 📦 The release manifest records seven files, not six:
tool-verdicts.jsonis the seventh. read more - ⬆️ Every release builds against the latest Playwright, and the one override is a human's. read more
- 📝 Adversarial and hostile-caller defence is a stated non-goal. read more
- 📝 Two hazards that lost their protection when the filename gate went are adjudicated and stay open. read more
- 📝 A just-answered call can read as still in flight, and that is now written down. read more
- 🔒
browser_start_recordingandbrowser_stop_recordingare judgedallow. read more - 📝 The server instructions told models something false about screenshots. read more
- 🔧 The refusal for an unjudged tool used to tell the caller to send it again. read more
- 📦
build/Build-Payload.ps1setsPLAYWRIGHT_SKIP_BROWSER_GC=1, as the product always has. read more - 📝 Two upstream asks were transferred by upstream itself. read more
- 🔧 An aliased session directory is resolved rather than refused. read more
- 🔧
browserai_listpointed at an alias of a tree now finds the sessions under it. read more - ⚡
browserai_listno longer parses every session record on the machine. read more - 🔧 The machine-wide log is one shared file under a cross-process write gate. read more
- 🔧 Rotation happens exactly at the cap. read more
- ♻️
BrowserAiPathsno longer claims to answer "the directory the product would actually have used". read more - ✅ The release gate's two shells are two instruments by construction. read more
- 📝
browser_get_configDOES redactsecrets, and three places said otherwise. read more - 🔒 BrowserAI refuses to serve out of an app root that is not inside the current user's Windows profile. read more
- 🔧 The claim on the browsers root is a reader/writer lock. read more
- 🔧 Every refusal a caller meets during a long operation now says how far in it is. read more
- ✅ The provisioning stall detector runs on an injected clock and byte source. read more
- 💥 A session's record is
browserai.json, renamed fromlock.json. read more - 🔒
allowUnrestrictedFileAccessis set in every generated child config, always. read more - 🔧 Provisioning is stopped when it stops making progress, not when it has taken too long. read more
- 🔧 The refusal a browser call meets while provisioning runs is a progress report. read more
- 📝
QUESTIONS.mdhad gone stale, and it is the document the maintainer reviews from. read more - 🔧
browserai_destroyreturnsisError: truewhen it could not remove everything. read more - ✅ CI declares which capabilities it expects to be absent, and an undeclared absence is a red build. read more
- 📝 A recorded hazard was measured and turned out not to be one. read more
- 📝 Every row of the hazard index is now adjudicated. read more
- 💥
browserai_reinstall_browsernow takes one required argument, naming the family. read more - 🔒 A session directory on a network path is refused, and a mapped drive letter counts as one. read more
- 🔒 A second spelling of one session directory is refused, with the spelling to use instead. read more
- 📝 The charter said there is no CI, and there has been since 2026-08-18. read more
- 📝 The browser-reinstall row rests on a measurement of Chromium. read more
- 📝
@playwright/mcpemits no progress notifications at all. read more - 📝
LongPathsEnabledis recorded where the long-path guarantee is claimed. read more - ♻️
CreateProcessW's two buffers are declared as spans rather than as onechar. read more - 🔧
.gitignore: the three owed items, and one of them was a claim that was not true. read more - 💥
lock.jsonis schema 2: every field is an ordered list of statements. read more - 🔧 A contender asks the kernel who holds a session before it queues for the right to ask. read more
- 🔧
browserProvisioningnow answersprovisioningwhere it answereddownloading. read more - 📝
CLAUDE.mdis 50 lines instead of 89, and every rule names its mechanism. read more - 📝 The charter is split in two, and
README.mdis a README again. read more - 📝 The hazard index says what each step was rather than where it stood. read more
- 🔧 The stray-browser sweep now has one trigger instead of two. read more
- ♻️ One place answers "what version is this binary". read more
- 📦 The SDK is forbidden from decorating the version string. read more
- 📦 The RID section a restore writes into
BrowserAI.Core's lock file is committed, not reverted. read more - 📝 First-run provisioning is measured again at the new browser revisions. read more
- ✅ The one suite arm that launches an unowned browser runs beside nothing. read more
- 🐛 A browser call into a session whose server has gone comes back now. read more
- 🔧
browserai_resumerepairs a session whose browser server has died. read more - ⬆️
playwright-coreis pulled one build ahead of the wrapper that pins it, as a dated exception. read more - 📝 The resume wedge is measured, and nothing in the product bounds it. read more
- 📝 The wild exit 1 has a name at last, and it is this product's own stray sweep. read more
- 📝 The 1.0.0 release note opens in plain words now. read more
- 🔧 The icon legend is a compact table now, in the release body and in this file. read more
- 📝 Two records catch up: where the probe rigs live, and what upstream did with the first ask. read more
- 📝 Chromium stays the default browser, on a reason rather than on four numbers that moved. read more
- 📝 The upstream record catches up: one ask granted, one fix declined, one count reconciled. read more
- ✅
NeverByImageNameTestsreads the filter rather than the API. read more - ✅ A pid that vanishes between the walk and the query is exited, not unknown. read more
- 🔧
BrowserAI.Coredeclares its RID, and the lock file has one state. read more - ⬆️ TUnit moved 1.67.0 → 1.68.4 and Microsoft.Testing.Platform deliberately did not move at all. read more
Removed
- 🗑️
browserai-sessions.json, the per-root roll-up, and every mechanism that wrote it. read more - 🗑️
consoleLevel, and the four-level choice behind it. read more - 🗑️ Session modes. read more
- 🗑️ Continuous integration, completely. read more
- 🗑️
SuiteCoverageTests.TheWorkflowStillDeclaresWhatItExpectsToBeAbsentis deleted. read more - 🗑️
BuildConfigurationTests.NoSourceFileIsInvisibleToGitis deleted, deliberately. read more - 🗑️
browser_annotateis gone from the model-facing surface. read more - 📝 The sweep's two highest-value assumptions are measured. read more
- 📝 The justification sweep: 598 load-bearing reasons sorted. read more
- ✅ The client's "2KB each" is per string, and the gate was measuring the wrong unit. read more
- 🗑️ BrowserAI advertised an MCP capability it does not implement. read more
- ✅ The test double was more capable than the thing it doubles. read more
- 🐛
browserProvisioningsaiddownloadingwhen this process had started no download. read more - 🐛 A supported configuration warned on every startup. read more
- ✅
HazardIndexTests.EveryRowIsOpenOrClosedAndNothingElseenforces its own name now. read more - 📝 Four counts in prose were wrong. read more
- 🗑️ The free-space check is gone, and nothing asks a volume how much room it has. read more
Fixed
- 🐛 A launcher that had exited but whose pid still opened was read as a live client. read more
- 🐛 BrowserAI 1.0.0 did not exit when it had nobody to serve, and every install left orphans. read more
- ⚡ A run with nobody to serve started a browser server before working out nobody was there. read more
- ✅ The suite's installer arm destroyed the maintainer's Add/Remove Programs entry. read more
- ✅ The release gate's ILC check could not fail. read more
- ✅ Release checklist item 8's code fence set the release variable and nothing else. read more
- ✅ The harness's process-log reader answered with a stranger's records. read more
- ✅ The suite's reclaim pass could terminate a live run's processes machine-wide. read more
- ✅ The guard on the
[STALE]marker forbade the one resolution its own failure message prescribed. read more - ⚡ Starting the server opened the SQLite store of every session on the machine. read more
- 🐛 An idle browser close left no trace in the only record there is. read more
- 🐛 An unjudged
browserai_name was refused without being recorded. read more - 🔒 A
purposeor awhycould carry invisible supplementary-plane text into another agent's context. read more - 🐛
browserai_catch_upserved an out-of-rangepageas a different page. read more - 🔒 A refusal echoed the caller's own control characters back into the model reading it. read more
- 🐛 A refusal leaked a C# parameter name. read more
- 🐛 A session directory too deep to hold its own
browserai.datawas accepted, created and locked. read more - 🐛 A duplicate tool name in
tool-verdicts.jsonexited naming neither the file nor the row. read more - 🐛
browserai_liston a drive letter with nothing mounted on it answered "no sessions". read more - 🔒 Five
PLAYWRIGHT_MCP_*variables are refused by name rather than merely absent. read more - ✅ A suite arm lost the machine-wide sweep gate to a BrowserAI another test started. read more
- ✅ The two literals the session guard is made of are now held by a test. read more
- ✅ The re-verification index's gate now reads around a
previously "…"clause. read more - 🐛
browserai_listsaidin use: noabout a session another agent was driving right now. read more - 🔒 Page content could switch the artifact-pointer protection off. read more
- 🐛 Every failure to open
reinstall.lockwas reported as a reinstall in progress. read more - 🐛 A pinned artifact name was matched undelimited and never given back. read more
- 🐛 A cancelled
tools/callleaked its filename reservation for the life of the session. read more - 🐛 A torn log record is no longer possible. read more
- 🐛 Nothing can unlink the live machine-wide log out from under its writers. read more
- 🐛 A
browserai_destroyracing abrowserai_set_purposeleaked the session directory. read more - 🐛 One junction above the install root made the stray sweep structurally blind. read more
- 🐛 The instance directory's liveness rested on one child. read more
- 🐛 The pointers BrowserAI handed the model did not resolve. read more
- 🐛 755 stale
.livemarkers had accumulated, and nothing ever reclaimed them. read more - 📝 The mode table claimed a persistence property the code has never had. read more
- 📝 Two doc comments claimed a refusal that has not existed since 2026-08-18. read more
- 🐛 The reclaim pass had a bullet with no input for three days, and it read as though it worked. read more
- ✅ The failed-rewrite recovery of
lock.jsonhas a test. read more - 🐛 The two ungated
lock.jsonreaders that acted on an absence are closed. read more - 🐛 Two BrowserAI processes wrote holder statements into one
lock.json. read more - ✅ The suite was red from Git Bash and green from PowerShell on the same commit. read more
- 🐛 A durable write that landed said nothing was changed. read more
- 📝 Not fixed, and recorded loudly: two processes appended to one
lock.jsonin CI. read more - ✅ A probe wrote its report in place, so
File.Existsbecame true mid-write. read more - 🐛 A screenshot comes back inline again, and the defect was ours. read more
- 🐛 Closing the process log did not close its file. read more
- 🐛 A second BrowserAI starting up deleted a running one's working files. read more
- 🐛 An instance directory that would not go now says which file held it. read more
- 🐛 A
session.jsonthat could not be written was silent. read more - 📦 Two licences that had to travel with the binary were not travelling. read more
- ✅ A suite run that exercised nothing reported exactly what a real one reports. read more
- 📦 37 MB of every release was a zip nobody reads. read more
- ✅
UseSystemResourceKeysis asserted rather than merely set. read more - 🐛 Every session's
lock.jsonwould have recorded the wrong version. read more - 📝 Six stale sentences are corrected and one new hazard is written down. read more
- ✅ The app's embedded manifest and its apartment are asserted off the binary that ships. read more
- 🐛 The installer's own variables are cleared after Velopack has read them, not before. read more
- 🔧 The dialog's icon is loaded at the dialog's DPI instead of at the classic size. read more
- 🐛 The release-notes generator refuses the two shapes it used to crash on or drop. read more
- 🔧 A wait on the client's handle that cannot be interpreted now records the value it got. read more
- ✅ A release date set at the cut is reported as a heading change, not as a rewritten record. read more
- 📦 A release cut over a local feed still holding this machine's gate packs is refused. read more
- 🔧 The update check runs off the UI thread, under the same deadline the server uses. read more
- 🐛 The folder picker is owned by the dialog, and an unresolvable folder is no longer a silent cancel. read more
- 🐛 A click that throws no longer takes the whole window with it. read more
- 🔒 Neither an install nor an uninstall touches a
browseraientry it did not write. read more - 📦 The suite's installer is titled
BrowserAI (suite)and no longer owns the real Start Menu entry. read more - 🐛 Three invisible backspace bytes are gone, and one of them had silenced a whole scan. read more
- ✅ No text file in the tree may carry a C0 control byte. read more
- 🐛 An "ours" registration that names the wrong binary is stale, not present. read more
- 📦 A release body is one shape now: a headline a line, each linked to its own lines of the changelog. read more
- 📝 A publish leaves
BrowserAI.Core's lock file modified, whichever publish it is. read more - 🐛 A read-only file no longer defeats the delete every tree delete goes through. read more
- ✅ The dated dependency override cannot be forgotten: two instruments go red on the day it expires. read more
- 🐛 The coverage block stops printing a download size somebody typed. read more
- 📦
New-Release.ps1clears its own test feed before it packs into it. read more - 📦 The release checklist now clears the suite's feed as well as the real one. read more
| Icon | Meaning | Icon | Meaning |
|---|---|---|---|
| ✨ | new capability | 🐛 | fix |
| 🔧 | behaviour or configuration change | 🔒 | security or permissions |
| 🗑️ | removal or deprecation | 💥 | breaking, or the reader must act |
| 📝 | documentation | ✅ | tests and the gate |
| 📦 | packaging, installer, release pipeline | ⚡ | performance |
| ♻️ | refactor with no behaviour change | ⬆️ | dependency move |
The full changelog for this release: CHANGELOG.md