Backpack MCP
by Elfiawesome
README.md
# Backpack MCP
Backpack MCP is a self-contained browser bridge that turns websites you are already signed in
to into [Model Context Protocol](https://modelcontextprotocol.io) tools. It runs from a cloned
repository, uses a local Python environment and a local Chromium install, and includes a local
dashboard for signing in and administering extensions.
There is no package build, installer or `.exe`. `backpack.cmd` sets up the local environment on
first run and then runs the Python server.
> Backpack automates accounts and sites you are authorised to use. Automating a website may
> violate its terms of service. You are responsible for how you use it.
## Requirements
- Python 3.11 or newer on `PATH`
- Windows for `backpack.cmd` (macOS/Linux can use the module entry point)
- Network access on first run for Python dependencies and the local Chromium download
## Why Backpack
- **Self-contained.** The Python environment, Chromium, profiles, cookies, screenshots,
downloads, logs and settings all live inside the cloned folder. Deleting `.backpack/` resets
site data.
- **Browser-first.** No vendor API keys are required. Backpack uses real, persistent browser
profiles, so it uses the same sessions you sign in to.
- **Headless by default.** Full Chromium new-headless mode is used for tool calls. A visible
window is only opened for sign-in or verification, and live screenshots are available on demand.
- **Extension driven.** Every site is a small Python class with typed tools. Adding a website
does not require changing Backpack's core.
- **One browser owner.** A local daemon owns the browser, so the dashboard and MCP clients share
sessions without Chromium profile-lock races.
## Clone and run
```powershell
git clone <repository-url> backpack-mcp
cd backpack-mcp
.\backpack.cmd browser install
.\backpack.cmd ui
```
On first run, `backpack.cmd` creates `.venv/`, installs `requirements.txt`, and then runs the
CLI. Chromium is downloaded into `.backpack/browsers`. No global packages are installed.
If PowerShell blocks local scripts, use `cmd /c backpack.cmd ...` or run the command from a
regular Command Prompt.
On macOS or Linux, create a local venv and use the module entry point:
```bash
python -m venv .venv
.venv/bin/python -m pip install -r requirements.txt
.venv/bin/python -m backpack_mcp browser install
.venv/bin/python -m backpack_mcp ui
```
## Dashboard and login
`.\backpack.cmd ui` starts the local daemon and opens the dashboard. Use **Open setup** for each
site, sign in, and close the window. Headless tool calls reuse that profile.
For sites that show a Cloudflare verification page, keep the setup window open for the tool call.
Backpack reports verification challenges instead of silently failing. If a site keeps challenging
headless sessions, add this to its settings in the dashboard:
```json
{ "force_headed": true }
```
The dashboard screenshot view is manual by default. Do not enable **Live** while you are
interacting with a CAPTCHA or verification widget; repeated captures can interfere with it.
The dashboard is protected by a loopback-only token. If you lose the URL, run
`.\backpack.cmd ui` again or `.\backpack.cmd daemon status --url`.
## Built-in site extensions
| Extension | Tools | Description |
| --- | --- | --- |
| Consensus | `consensus__ask` | Research answers, citation links and the Consensus Meter |
| DeepSeek | `deepseek__ask`, `deepseek__new_chat` | Chat with optional DeepThink reasoning and web search |
| Arena | `arena__battle`, `arena__side_by_side`, `arena__direct`, `arena__models` | Anonymous battles, selected model pairs and direct chat |
| Google | `google__search` | AI Overview, cited sources and organic results |
Built-ins live in `backpack_mcp/extensions/builtin/`. Project extensions live in `extensions/`
and load after the built-ins.
## MCP client configuration
Point the client at `backpack.cmd` through `cmd.exe` so batch-file setup works reliably:
```json
{
"mcpServers": {
"backpack": {
"command": "C:\\Windows\\System32\\cmd.exe",
"args": [
"/c",
"C:\\path\\to\\backpack-mcp\\backpack.cmd",
"serve"
],
"cwd": "C:\\path\\to\\backpack-mcp"
}
}
}
```
`backpack.cmd serve` runs the MCP stdio server and starts the daemon automatically if it is not
already running. It exposes:
- Generic tools: `backpack_list_extensions`, `backpack_status`, `backpack_list_tools`,
`backpack_screenshot`, `backpack_open_login`, `backpack_close_browser`,
`backpack_reload_extensions`, `backpack_logout`
- Extension tools namespaced as `<extension>__<tool>`
Ask your client to call `backpack_list_extensions` first.
## Writing an extension
```python
from typing import Annotated
from playwright.async_api import Page
from pydantic import Field
from backpack_mcp.extensions import BackpackExtension, ToolResult, tool
class ExampleExtension(BackpackExtension):
id = "example"
name = "Example"
description = "A minimal extension."
site = "https://example.com"
requires_login = False
@tool(description="Return the page title.", read_only=True)
async def title(self, page: Page) -> ToolResult:
return ToolResult.ok(await page.title())
@tool(description="Search the site.")
async def search(
self,
page: Page,
query: Annotated[str, Field(description="Search query")],
) -> ToolResult:
await self.ctx.goto(page)
...
```
Create a starter with:
```powershell
.\backpack.cmd extensions new mysite --name "My Site" --site https://example.com
```
The `extensions/_template` directory and the `examples/demo` extension are reference material.
See [Writing extensions](docs/extensions.md) for the full API.
## Self-contained data
Everything Backpack persists is under `.backpack/` (or `BACKPACK_HOME` when set):
```text
.backpack/
browsers/ # project-local Playwright Chromium
profiles/<id>/ # persistent browser profile per extension
screenshots/ # retained screenshots
downloads/<id>/ # files downloaded by a session
settings/ # per-extension JSON settings
logs/ # rotating application and daemon logs
runtime/ # daemon metadata and local API token
tmp/ # temporary browser files
```
The Python environment lives in `.venv/`. To reset Backpack, stop the daemon and delete
`.backpack/`; then run `.\backpack.cmd browser install` again. Use
`.\backpack.cmd logout <id>` to clear one site only.
## Security
- The daemon binds to loopback only and requires a random per-process token.
- Browser profiles are credentials. Keep `.backpack/` private and never commit it.
- Extension code runs as local Python with your privileges. Only install extensions you trust.
- Backpack does not send telemetry and does not use external CDN assets in its dashboard.
- Backpack does not solve CAPTCHAs or bypass access controls. Use it within each site's terms.
## CLI reference
All commands go through the root launcher:
| Command | Purpose |
| --- | --- |
| `.\backpack.cmd browser install` | Install Chromium under `.backpack/browsers` |
| `.\backpack.cmd browser status` | Check for the local Chromium build |
| `.\backpack.cmd ui` | Start the daemon and open the dashboard |
| `.\backpack.cmd ui --foreground` | Run the daemon in the current terminal |
| `.\backpack.cmd serve` | Run the MCP stdio server |
| `.\backpack.cmd login <id>` | Open a visible browser window for an extension |
| `.\backpack.cmd logout <id>` | Delete an extension's profile and settings |
| `.\backpack.cmd status` | Show project, daemon, browser and extension status |
| `.\backpack.cmd doctor` | Run local diagnostics |
| `.\backpack.cmd extensions list` | List extensions and their tools |
| `.\backpack.cmd extensions new <id> --name ... --site ...` | Create a new extension |
| `.\backpack.cmd extensions reload` | Reload extension code in the running daemon |
| `.\backpack.cmd daemon start\|stop\|restart\|status` | Manage the local daemon |
## Library use
Backpack can also be imported from another Python program. Run that program from the repository
root, or put the repository root on `PYTHONPATH`:
```python
import asyncio
from backpack_mcp import Backpack
async def main() -> None:
async with Backpack() as backpack:
tools = await backpack.list_tools()
print([tool["name"] for tool in tools])
result = await backpack.invoke(
"google__search",
{"query": "what causes thunder", "num_results": 5},
)
print(result.text)
asyncio.run(main())
```
Library mode owns the browser in-process. Do not use it against the same profiles while the
daemon is running.
## Documentation
- [Architecture](docs/architecture.md)
- [Writing extensions](docs/extensions.md)
- [Configuration reference](docs/configuration.md)
## Development
```powershell
python -m venv .venv
.\.venv\Scripts\python.exe -m pip install -r requirements-dev.txt
.\.venv\Scripts\python.exe -m ruff check backpack_mcp tests extensions examples
.\.venv\Scripts\python.exe -m ruff format --check backpack_mcp tests extensions examples
.\.venv\Scripts\python.exe -m mypy
.\.venv\Scripts\python.exe -m pytest
```
Unit and API tests do not require a browser. Browser integrations are tested manually because
they depend on signed-in site profiles and live third-party UIs.
## License
MIT. See [LICENSE](LICENSE).
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo recent community issues