Skip to main content
Glama
thenailedone

firefox-browser-control

by thenailedone
README.md
# Firefox Browser Control for Codex

Control the Firefox session you already have open from Codex. The plugin can list and organize non-private tabs, create native tab groups, and safely open, activate, navigate, or close tabs.

The Firefox extension and its bridge run locally, with no TCP listener, telemetry, advertising, or direct extension network requests. Browser data requested by the user is passed to their configured Codex environment; see the [privacy policy](PRIVACY.md).

## What it can do

- Check whether the Firefox companion extension is connected.
- List tabs and native tab groups.
- Group selected tabs or group tabs by URL/title matches.
- Ungroup, open, activate, navigate, and close tabs.

It intentionally cannot read page content, click elements, fill forms, inspect private windows, or navigate to non-HTTP(S) URLs.

Example prompts:

- “Group my open Gmail tabs in Firefox.”
- “List my open Firefox tabs.”
- “Open the project documentation in a new Firefox tab.”

## Install

See [plugins/firefox-browser-control/INSTALL.md](plugins/firefox-browser-control/INSTALL.md) for the full setup. In short:

```bash
git clone https://github.com/thenailedone/firefox-browser-control.git
cd firefox-browser-control
codex plugin marketplace add "$PWD"
codex plugin add firefox-browser-control@firefox-browser-control
node plugins/firefox-browser-control/scripts/install-native-host.mjs
```

Install the signed extension from Mozilla Add-ons when it becomes available. During development, load `plugins/firefox-browser-control/extension/manifest.json` temporarily from `about:debugging#/runtime/this-firefox`. Then start a new Codex task.

## How it works

The implementation is a four-part local bridge:

```text
Codex
  │ MCP over stdio
  ▼
MCP server (Node.js)
  │ newline-delimited JSON over a user-only Unix socket
  ▼
Firefox native-messaging host (Node.js)
  │ Firefox native messaging over stdin/stdout
  ▼
Firefox WebExtension
  │ WebExtension APIs
  ▼
Non-private tabs and tab groups in the running Firefox profile
```

1. Codex discovers `.mcp.json` from the plugin manifest and launches `scripts/mcp-server.mjs`.
2. The MCP server exposes strongly described tools such as `firefox_list_tabs` and `firefox_group_tabs`.
3. A tool call is assigned a random request ID and sent through the local Unix socket.
4. `scripts/native-host.mjs` relays that request through Firefox's length-prefixed native-messaging protocol.
5. `extension/background.js` executes the requested operation with Firefox WebExtension APIs and returns a result along the same path.

The native host owns the socket for as long as the Firefox extension is connected. The MCP server makes a short-lived socket connection for each tool call, so no background daemon is required outside Firefox.

## Why there are two protocols

Codex speaks Model Context Protocol over stdio, while Firefox extensions can talk to local programs only through native messaging. The small Unix-socket relay connects those environments without opening a TCP port or exposing the browser to the network.

## Tool surface

| Tool | Purpose |
| --- | --- |
| `firefox_status` | Confirm that the extension and native bridge are connected. |
| `firefox_list_tabs` | Return tab IDs, sanitized origins, windows, and group IDs. |
| `firefox_list_groups` | List native Firefox tab-group IDs and display state. |
| `firefox_group_tabs` | Put explicit tab IDs into a named group. |
| `firefox_group_tabs_by_url` | Match tabs by URL/title and group them per window. |
| `firefox_ungroup_tabs` | Remove tabs from their current group. |
| `firefox_open_tab` | Open a URL. |
| `firefox_navigate_tab` | Navigate a selected tab. |
| `firefox_activate_tab` | Focus a tab and its window. |
| `firefox_close_tabs` | Close selected tabs. |

## Security model

- The bridge listens on a Unix socket, not a network port.
- The socket is restricted to the current operating-system user (`0600`).
- Firefox accepts native messages only from the extension ID declared by the installer.
- Private-browsing tabs are invisible to the extension.
- Full URLs, URL queries/fragments, page titles, and page content are not returned to Codex; tab-list results contain origins only.
- The MCP server enforces explicit JSON Schemas and a fixed tool-to-method mapping.
- Requests time out after ten seconds.
- The extension performs only the tab methods in its fixed dispatcher and restricts navigation to HTTP(S) URLs plus `about:blank`.
- The temporary-directory fallback creates a per-user `0700` directory, and the socket is `0600`.

The extension requests no website host permissions and makes no direct network requests. It transmits sanitized browsing activity only when the user initiates a Codex tab-management command.

## Repository layout

```text
.agents/plugins/marketplace.json             Codex marketplace catalog
plugins/firefox-browser-control/
  .codex-plugin/plugin.json                  Plugin metadata
  .mcp.json                                  MCP server launch configuration
  extension/                                 Firefox WebExtension
  scripts/mcp-server.mjs                     MCP tool server
  scripts/native-host.mjs                    Firefox/native-socket relay
  scripts/install-native-host.mjs            Native-host installer
  scripts/review-client.mjs                  Standalone reviewer test client
  skills/control-firefox/SKILL.md            Agent usage guidance
```

## Development

Run the repository checks with Node.js 20 or later:

```bash
npm test
```

Build the AMO-ready extension archive:

```bash
npm run build:extension
```

The ZIP is written to `artifacts/`. Store listing copy, reviewer instructions, and the submission checklist are in [store/AMO_SUBMISSION.md](store/AMO_SUBMISSION.md).

After changing the extension, use **Reload** beside the temporary add-on in `about:debugging`. After changing plugin metadata, the skill, or MCP server, reinstall the plugin and start a new Codex task.

## Limitations

- The extension is unsigned and must be loaded again after Firefox restarts.
- Automatic native-host installation currently supports Linux and macOS.
- The relay currently uses Unix sockets and does not support native Windows.
- The extension requires Node.js, the native host, and either Codex or the standalone review client.
- This is an independent community integration and is not affiliated with or endorsed by Mozilla or OpenAI.

## License

[MIT](LICENSE)