CLI tool to manage Firefox tabs from the terminal — list, open, close, and organize tabs into groups.
tabs CLI → Unix socket → native-host.js → Firefox extension → browser.tabs API
A Firefox WebExtension connects to a native messaging host, which also listens on a Unix socket at /tmp/firefox-tabmanager.sock. The CLI talks to that socket.
The extension also shows the total tab count as a toolbar badge and the active tab's ID in the tooltip.
- Node.js
- Firefox
web-extfor signing:npm install -g web-ext
git clone <this-repo> ~/code/tabmanager
cd ~/code/tabmanager
./install.shThis does three things:
- Installs the native messaging manifest to
~/Library/Application Support/Mozilla/NativeMessagingHosts/ - Symlinks
cli/tabs.jsto~/bin/tabs - Makes scripts executable
For quick testing, load temporarily via about:debugging:
- Open
about:debugging#/runtime/this-firefoxin Firefox - Click "Load Temporary Add-on..."
- Select
extension/manifest.jsonfrom this repo
The extension will be removed when Firefox restarts.
Sign the extension as unlisted (free, no public listing, no review):
- Create an AMO developer account at https://addons.mozilla.org/developers/
- Generate API keys at https://addons.mozilla.org/developers/addon/api/key/
- Sign the extension:
cd extension
web-ext sign --channel=unlisted \
--api-key=YOUR_JWT_ISSUER \
--api-secret=YOUR_JWT_SECRET- This creates a signed
.xpifile inweb-ext-artifacts/ - Install it in Firefox: open
about:addons→ gear icon → "Install Add-on From File..." → select the.xpi
The extension will now persist across Firefox restarts.
# List all tabs across all windows (JSON)
tabs list
# Pretty-print with jq
tabs list | jq .
# Get just URLs
tabs list | jq '.windows[].tabs[].url'
# Find active tabs
tabs list | jq '.windows[].tabs[] | select(.active)'
# Find tabs in a specific group
tabs list | jq '.windows[].tabs[] | select(.group)'
# Open a URL
tabs open https://example.com
# Close a tab by ID
tabs close 42
# Close all tabs in a group
tabs close-group 5
# Create a named group from tabs
tabs create-group work 42,43,44
# Add tabs to an existing group
tabs add-to-group 5 45,46
# Remove tabs from their group
tabs remove-from-group 42,43tabs list returns JSON with this structure:
{
"tabCount": 12,
"windowCount": 2,
"groupCount": 1,
"windows": [
{
"id": 3,
"focused": true,
"tabCount": 8,
"tabs": [
{
"id": 42,
"title": "GitHub",
"url": "https://github.com",
"active": true,
"pinned": false
},
{
"id": 43,
"title": "Docs",
"url": "https://docs.example.com",
"active": false,
"pinned": false,
"group": "Work:5",
"groupColor": "blue"
}
]
}
]
}- Tabs without a group omit the
groupandgroupColorfields groupformat is"title:id"(e.g."Work:5")
"cannot connect to native host"
- Is the Firefox extension loaded? Check
about:addons - Check the socket exists:
ls -la /tmp/firefox-tabmanager.sock - Check Firefox console (
about:debugging→ Inspect) for native messaging errors
"timed out waiting for response"
- The native host may have crashed. Check
about:debugging→ Inspect the extension for errors - Try reloading the extension
Extension doesn't connect after install
- Verify the native messaging manifest exists:
cat ~/Library/Application\ Support/Mozilla/NativeMessagingHosts/tab_manager.json - Verify the
pathin that file points to the correct absolute path ofhost/native-host.js - Verify
native-host.jsis executable:ls -la host/native-host.js