Skip to main content
Glama
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).