A Firefox extension that exposes browser functionality to AI assistants and automation tools through the Model Context Protocol (MCP). Control tabs, history, bookmarks, navigation, content, and windows programmatically.
FoxMCP enables AI access to your browser data. Use only with trusted AI services and consider using dedicated browser profiles for testing.
curl -L https://github.com/ThinkerYzu/foxmcp/releases/download/v1.3.0/install-from-github.sh | bash
This script automatically:
Install Firefox Extension:
After running the installation script, install the FoxMCP extension from Firefox Add-ons:
# Clone repository
git clone https://github.com/ThinkerYzu/foxmcp.git
cd foxmcp
# Create venv/ and install the server dependencies into it
make install
Python 3.10 or newer is required — fastmcp 3 does not install on anything older.
Development and CI run 3.14, and 3.12 is verified. make install creates venv/ and
installs server/requirements.txt into it; use make setup instead if you also want
to run the test suite, which adds tests/requirements.txt.
You also need make, zip and Python's venv module, none of which a stock Ubuntu
has: sudo apt install make zip python3-venv. Without python3-venv, make install
stops at "The virtual environment was not created successfully"; without zip,
make package cannot build the XPI.
# Build and package extension
make package
Your Firefox channel decides which methods are available. Release and Beta
builds enforce extension signing and ignore xpinstall.signatures.required, so an
unsigned XPI cannot be installed permanently on them — only Nightly, Developer
Edition and unbranded builds honour that preference, which Methods 2 and 3 depend
on. On Release or Beta, either install the signed copy from
Firefox Add-ons, or use
Method 1, which loads an unsigned XPI temporarily until Firefox restarts.
Install in Firefox (Method 1 - Temporary Add-on):
about:debuggingdist/packages/foxmcp@codemud.org.xpiInstall in Firefox (Method 2 - Persistent with Preferences):
about:config (accept the warning)xpinstall.signatures.required to falseextensions.experiments.enabled to true (if needed)about:addonsdist/packages/foxmcp@codemud.org.xpiInstall in Firefox (Method 3 - Automated Script):
# IMPORTANT: Close Firefox completely first!
# Find your profile directory in about:profiles, then:
./scripts/install-xpi.sh /path/to/firefox/profile
This script automatically:
Then enable it by hand. Start Firefox, open about:addons, and turn FoxMCP on.
Firefox installs an extension dropped into a profile in the disabled state and
requires a person to enable it — no script can do that step, and until you do, the
extension is present, listed, and not running. Methods 1 and 2 install through the
browser, so they do not need it.
Note: Method 1 requires reinstalling after Firefox restarts. Method 2 requires manual preference changes. Method 3 is the least manual of the persistent options, on a channel that allows unsigned extensions — but it still needs that one click.
If you used the GitHub installation script:
# Use the provided startup script
./start-foxmcp.sh
If you installed from source:
# Start both WebSocket and MCP servers
make run-server
# Or the same thing by hand — note the interpreter, which is the one make uses
venv/bin/python server/server.py
Neither needs the virtual environment activated: both name venv/bin/python
directly. Activating it first (source venv/bin/activate) is fine too.
The server will start on:
localhost:8765 (for Firefox extension)localhost:3000 (for AI clients)For Claude Code:
claude mcp add --transport http foxmcp http://localhost:3000/mcp/
For Other MCP Clients:
Connect to http://localhost:3000/mcp/
Or let the client start the server. With --stdio the server speaks MCP on
stdin and stdout instead of HTTP, so a client launches it on demand and there is
no step 3 to remember:
claude mcp add --scope project foxmcp -- $PWD/venv/bin/python \
$PWD/server/server.py --stdio
The extension connects the same way it always does, but two costs come with this
mode. Only one server can serve the extension, and under stdio every client
launches its own, so two claude sessions at once means the second one gets no
browser tools. And the server lives only as long as your client, while the
extension stops trying to reconnect after about four minutes without one.
If you run several clients, or short terminal sessions through the day, HTTP mode
is the easier setup. Read One session at a
time and The reconnect
gap first. The same page has the
.mcp.json any client can use.
Once connected, you can control Firefox through natural language:
"List all open tabs"
"Create a new tab with example.com"
"Get the text content from the current page"
"Search my browsing history for python tutorials"
"Take a screenshot of the current tab"
"Execute JavaScript: document.title"
text/* by default, configurable per
monitor. A binary response reports its size, not its bytes# Custom ports
python server/server.py --port 9000 --mcp-port 4000
# WebSocket only (no MCP)
python server/server.py --no-mcp
# MCP on stdin/stdout, for a client that launches the server itself
python server/server.py --stdio
# Bind a different host
python server/server.py --host 127.0.0.1
# Offer fewer tools, to keep them out of the MCP client's context
python server/server.py --disable-tools bookmarks,history
# Drop a group but keep one tool out of it
python server/server.py --disable-tools tabs --enable-tools tabs_capture_screenshot
All 35 tools are offered by default, costing an MCP client roughly 4,700 tokens of
context. --disable-tools leaves a group unregistered: windows, tabs,
bookmarks, navigation, content, requests, history, debug.
--enable-tools names individual tools to register anyway, for when one tool out
of a group is the one you want. See
docs/configuration.md for what
each group costs.
Click the FoxMCP extension icon to configure:
Create reusable JavaScript automation with external scripts:
export FOXMCP_EXT_SCRIPTS="/path/to/your/scripts"
#!/bin/bash
# highlight_text.sh - Highlight text on page
search_text="${1:-example}"
echo "(function() {
// JavaScript to highlight text
return 'Highlighted: ' + search_text;
})()"
"Run the highlight_text script with 'important' as the search term"
The claude-ex/ directory contains example CLAUDE.md templates that help Claude Code understand how to create predefined external scripts. Copy claude-ex/CLAUDE.md.template to your project's CLAUDE.md to enable Claude Code to:
The predefined-ex/ directory includes ready-to-use scripts. To use them, point FOXMCP_EXT_SCRIPTS to the predefined-ex/ directory:
export FOXMCP_EXT_SCRIPTS="/path/to/foxmcp/predefined-ex"
YouTube Control (youtube-play-pause.sh):
youtube-play-pause.sh [play|pause|toggle]Google Calendar Scripts:
gcal-daily-events-js.sh - Extract events for a specific daygcal-monthly-events-js.sh - Extract events for the entire monthgcal-cal-event-js.sh - Extract detailed event informationDOM Simplification (dom-summarize.sh):
dom-summarize.sh [onscreen] [withpos]See docs/scripts.md for detailed documentation on creating and using predefined scripts.
# Setup development environment
make dev
# Run tests
make test
# Development cycle
make build && make run-server
See Development Guide for detailed instructions.
curl -i http://localhost:8765.
A healthy answer is 426 Upgrade Required — that is the WebSocket server
turning away a plain HTTP request. Connection refused means it is not runningThe server accepts WebSocket connections only from moz-extension:// origins, so a
handshake from anything but the extension is rejected with 403 and logged.
curl -i http://localhost:3000/mcp/. A 307 redirect to
/mcp means it is up; connection refused means it is not. A bare
curl http://localhost:3000 answers 404, which also proves the port is livechmod +x scripts/*.shmake testThis project is licensed under the MIT License - see the LICENSE file for details.
For detailed documentation, configuration options, and advanced usage, see the docs/ directory.
184 commits
Python
81.7%
JavaScript
9.2%
Shell
7.0%
Makefile
1.1%
A Firefox extension that exposes browser functionality to AI assistants and automation tools through the Model Context Protocol (MCP). Control tabs, history, bookmarks, navigation, content, and windows programmatically.
FoxMCP enables AI access to your browser data. Use only with trusted AI services and consider using dedicated browser profiles for testing.
curl -L https://github.com/ThinkerYzu/foxmcp/releases/download/v1.3.0/install-from-github.sh | bash
This script automatically:
Install Firefox Extension:
After running the installation script, install the FoxMCP extension from Firefox Add-ons:
# Clone repository
git clone https://github.com/ThinkerYzu/foxmcp.git
cd foxmcp
# Create venv/ and install the server dependencies into it
make install
Python 3.10 or newer is required — fastmcp 3 does not install on anything older.
Development and CI run 3.14, and 3.12 is verified. make install creates venv/ and
installs server/requirements.txt into it; use make setup instead if you also want
to run the test suite, which adds tests/requirements.txt.
You also need make, zip and Python's venv module, none of which a stock Ubuntu
has: sudo apt install make zip python3-venv. Without python3-venv, make install
stops at "The virtual environment was not created successfully"; without zip,
make package cannot build the XPI.
# Build and package extension
make package
Your Firefox channel decides which methods are available. Release and Beta
builds enforce extension signing and ignore xpinstall.signatures.required, so an
unsigned XPI cannot be installed permanently on them — only Nightly, Developer
Edition and unbranded builds honour that preference, which Methods 2 and 3 depend
on. On Release or Beta, either install the signed copy from
Firefox Add-ons, or use
Method 1, which loads an unsigned XPI temporarily until Firefox restarts.
Install in Firefox (Method 1 - Temporary Add-on):
about:debuggingdist/packages/foxmcp@codemud.org.xpiInstall in Firefox (Method 2 - Persistent with Preferences):
about:config (accept the warning)xpinstall.signatures.required to falseextensions.experiments.enabled to true (if needed)about:addonsdist/packages/foxmcp@codemud.org.xpiInstall in Firefox (Method 3 - Automated Script):
# IMPORTANT: Close Firefox completely first!
# Find your profile directory in about:profiles, then:
./scripts/install-xpi.sh /path/to/firefox/profile
This script automatically:
Then enable it by hand. Start Firefox, open about:addons, and turn FoxMCP on.
Firefox installs an extension dropped into a profile in the disabled state and
requires a person to enable it — no script can do that step, and until you do, the
extension is present, listed, and not running. Methods 1 and 2 install through the
browser, so they do not need it.
Note: Method 1 requires reinstalling after Firefox restarts. Method 2 requires manual preference changes. Method 3 is the least manual of the persistent options, on a channel that allows unsigned extensions — but it still needs that one click.
If you used the GitHub installation script:
# Use the provided startup script
./start-foxmcp.sh
If you installed from source:
# Start both WebSocket and MCP servers
make run-server
# Or the same thing by hand — note the interpreter, which is the one make uses
venv/bin/python server/server.py
Neither needs the virtual environment activated: both name venv/bin/python
directly. Activating it first (source venv/bin/activate) is fine too.
The server will start on:
localhost:8765 (for Firefox extension)localhost:3000 (for AI clients)For Claude Code:
claude mcp add --transport http foxmcp http://localhost:3000/mcp/
For Other MCP Clients:
Connect to http://localhost:3000/mcp/
Or let the client start the server. With --stdio the server speaks MCP on
stdin and stdout instead of HTTP, so a client launches it on demand and there is
no step 3 to remember:
claude mcp add --scope project foxmcp -- $PWD/venv/bin/python \
$PWD/server/server.py --stdio
The extension connects the same way it always does, but two costs come with this
mode. Only one server can serve the extension, and under stdio every client
launches its own, so two claude sessions at once means the second one gets no
browser tools. And the server lives only as long as your client, while the
extension stops trying to reconnect after about four minutes without one.
If you run several clients, or short terminal sessions through the day, HTTP mode
is the easier setup. Read One session at a
time and The reconnect
gap first. The same page has the
.mcp.json any client can use.
Once connected, you can control Firefox through natural language:
"List all open tabs"
"Create a new tab with example.com"
"Get the text content from the current page"
"Search my browsing history for python tutorials"
"Take a screenshot of the current tab"
"Execute JavaScript: document.title"
text/* by default, configurable per
monitor. A binary response reports its size, not its bytes# Custom ports
python server/server.py --port 9000 --mcp-port 4000
# WebSocket only (no MCP)
python server/server.py --no-mcp
# MCP on stdin/stdout, for a client that launches the server itself
python server/server.py --stdio
# Bind a different host
python server/server.py --host 127.0.0.1
# Offer fewer tools, to keep them out of the MCP client's context
python server/server.py --disable-tools bookmarks,history
# Drop a group but keep one tool out of it
python server/server.py --disable-tools tabs --enable-tools tabs_capture_screenshot
All 35 tools are offered by default, costing an MCP client roughly 4,700 tokens of
context. --disable-tools leaves a group unregistered: windows, tabs,
bookmarks, navigation, content, requests, history, debug.
--enable-tools names individual tools to register anyway, for when one tool out
of a group is the one you want. See
docs/configuration.md for what
each group costs.
Click the FoxMCP extension icon to configure:
Create reusable JavaScript automation with external scripts:
export FOXMCP_EXT_SCRIPTS="/path/to/your/scripts"
#!/bin/bash
# highlight_text.sh - Highlight text on page
search_text="${1:-example}"
echo "(function() {
// JavaScript to highlight text
return 'Highlighted: ' + search_text;
})()"
"Run the highlight_text script with 'important' as the search term"
The claude-ex/ directory contains example CLAUDE.md templates that help Claude Code understand how to create predefined external scripts. Copy claude-ex/CLAUDE.md.template to your project's CLAUDE.md to enable Claude Code to:
The predefined-ex/ directory includes ready-to-use scripts. To use them, point FOXMCP_EXT_SCRIPTS to the predefined-ex/ directory:
export FOXMCP_EXT_SCRIPTS="/path/to/foxmcp/predefined-ex"
YouTube Control (youtube-play-pause.sh):
youtube-play-pause.sh [play|pause|toggle]Google Calendar Scripts:
gcal-daily-events-js.sh - Extract events for a specific daygcal-monthly-events-js.sh - Extract events for the entire monthgcal-cal-event-js.sh - Extract detailed event informationDOM Simplification (dom-summarize.sh):
dom-summarize.sh [onscreen] [withpos]See docs/scripts.md for detailed documentation on creating and using predefined scripts.
# Setup development environment
make dev
# Run tests
make test
# Development cycle
make build && make run-server
See Development Guide for detailed instructions.
curl -i http://localhost:8765.
A healthy answer is 426 Upgrade Required — that is the WebSocket server
turning away a plain HTTP request. Connection refused means it is not runningThe server accepts WebSocket connections only from moz-extension:// origins, so a
handshake from anything but the extension is rejected with 403 and logged.
curl -i http://localhost:3000/mcp/. A 307 redirect to
/mcp means it is up; connection refused means it is not. A bare
curl http://localhost:3000 answers 404, which also proves the port is livechmod +x scripts/*.shmake testThis project is licensed under the MIT License - see the LICENSE file for details.
For detailed documentation, configuration options, and advanced usage, see the docs/ directory.
184 commits
Python
81.7%
JavaScript
9.2%
Shell
7.0%
Makefile
1.1%