# Firefox Agent Bridge A small Firefox add-on that exposes an **allowlisted** WebExtension API to local scripts and agents — after you issue them a secret from inside Firefox. This is **not** a bookmark sync engine. Firefox already has `browser.bookmarks`. The add-on is a bridge: while Firefox is open, a script on the same machine can call those functions over `http://127.0.0.1:17634` with a Bearer token. Agents: start at [AGENTS.md](AGENTS.md). ## Why this exists Firefox will not let an outside process talk to Places. Editing `places.sqlite` while the browser is running loses deletes. The supported path is `browser.bookmarks` inside an extension, plus [native messaging](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Native_messaging) so a localhost HTTP host can reach that extension. ## Setup 1. Register the native host (once): ```powershell powershell -NoProfile -File tools\install-native-host.ps1 ``` 2. Load the add-on (`about:debugging` temporary, or a signed `.xpi` — [docs/signing.md](docs/signing.md)). 3. Click the toolbar icon → **Manage clients** → name a client → **Generate secret**. Copy the `fab_…` token into whatever secret store you already use. 4. Leave Firefox open. `GET http://127.0.0.1:17634/health` should return JSON. ## Call it ```powershell $env:FAB_TOKEN = "fab_…" # the value from the Manage clients modal python tools/client.py meta.methods python tools/client.py bookmarks.search '[{"title":"10.132.x.x"}]' ``` `curl` works the same: `Authorization: Bearer fab_…`. ## Security - Binds **127.0.0.1** only. Browser `Origin` headers are rejected. - Each caller is an issued token. The add-on stores a hash, not the secret. - Only `bookmarks.*` (plus `meta.*`) in `extension/background.js`. No history, cookies, tabs, or `onMessageExternal`. ## Pieces | Piece | Role | |-------|------| | `extension/` | Add-on, popup, Manage clients page | | `host/` | Native host: stdio to Firefox, HTTP to scripts | | `tools/client.py` | Bearer caller (`FAB_TOKEN`) | | `examples/replace_named_folder.py` | Sample folder replace | ## License MIT.