{
  "markdown": "# Brijio\n\n> **Remote agents. Local browser. No shared credentials.**\n\n<p align=\"center\">\n  <img src=\".github/images/hero.png\" alt=\"Brijio — Remote agents. Local browser. No shared credentials.\" width=\"800\" />\n</p>\n\nBrijio connects remote AI agents to the browser session you already control.\n\nInstead of launching a separate browser, cloning sessions, exporting cookies, or streaming screenshots, Brijio allows agents to collaborate with the browser you're already using.\n\nThe result is faster, safer, and more privacy-friendly access to the authenticated web.\n\nBrijio is open source under AGPLv3. See [LICENSE](LICENSE) and [COMMERCIAL-LICENSING.md](COMMERCIAL-LICENSING.md).\n\n---\n\n## Why Brijio?\n\nMost AI browser tools start with the assumption that the agent needs its own browser.\n\nBut in the real world, you're already:\n\n- logged into Workday\n- logged into Jira\n- logged into GitHub\n- logged into Gmail\n- logged into your company's internal tools\n\nThe challenge isn't giving a browser to the agent.\n\nThe challenge is allowing the agent to collaborate with the browser session you already control.\n\nThat's what Brijio solves.\n\n---\n\n## Key Principles\n\n### Authenticated Browser First\n\nUse the browser session you're already using.\n\n- No cookie export\n- No session replication\n- No browser cloning\n\n### Remote Agent Friendly\n\nRun agents wherever you want:\n\n- Claude Desktop\n- Codex\n- Gemini CLI\n- Hermes\n- OpenClaw\n- Cloud-hosted agents\n\nYour browser remains local.\n\n### Privacy By Design\n\nBrijio is intentionally reactive.\n\nThe browser does not continuously stream:\n\n- screenshots\n- page updates\n- DOM changes\n- browser history\n\nAgents must explicitly request information.\n\n### Progressive Disclosure\n\nAgents receive only the information they need.\n\nInstead of sending:\n\n- screenshots\n- massive DOM trees\n- full browser state\n\nBrijio provides structured context first, then content when requested.\n\n### Human In Control\n\nThe browser remains under user control.\n\nThe agent only receives access through explicit requests.\n\n---\n\n## Architecture\n\n```text\nAgent\n  ↓\nMCP Server\n  ↓\nBrijio Relay\n  ↓\nBrowser Extension\n ↓\nBrowser Session\n```\n\nThe browser remains the source of truth.\n\n```mermaid\nflowchart LR\n Agent[AI Agent] --> MCP[MCP Server]\n MCP --> WS[WebSocket Server]\n WS --> Ext[Browser Extension]\n Ext --> Browser[Current Browser Tab]\n\n Browser --> Ext\n Ext --> WS\n WS --> MCP\n MCP --> Agent\n```\n\n---\n\n## Capability Matrix\n\n- Read page context ✅\n- Read page content ✅\n- Read selected text ✅\n- Fill forms ✅\n- Trigger actions ✅\n- Read page metadata ✅\n- Structured page understanding ✅\n- Remote agent access ✅\n- File uploads 🚧\n- End-to-end encryption 🚧\n- Multi-tab workflows 🚧\n- Fine-grained permissions 🚧\n- Cookie export ❌\n- Session cloning ❌\n- Continuous browser streaming ❌\n- Browser recording ❌\n\nSee [docs/project/CAPABILITY_MATRIX.md](docs/project/CAPABILITY_MATRIX.md) for the full capability contract.\n\n---\n\n## Communication Flow\n\nThe extension is reactive. It should answer specific requests and return\nspecific results. It should not stream page state continuously.\n\n```mermaid\nsequenceDiagram\n participant User\n participant Agent as AI Agent\n participant MCP as MCP Server\n participant WS as WebSocket Server\n participant Ext as Browser Extension\n participant Tab as Browser Tab\n\n User->>Ext: Start bridge\n Ext->>WS: auth role=extension token\n WS-->>Ext: auth_success\n WS->>Ext: browser_presence_request\n Ext-->>WS: browser_presence_announce\n Agent->>MCP: tools/call list_browsers\n MCP->>WS: auth role=mcp token\n WS-->>MCP: auth_success\n MCP->>WS: list_browsers\n WS-->>MCP: browser_list\n Agent->>MCP: resources/read browser://page/current\n MCP->>WS: get_page_context target optional\n WS->>Ext: get_page_context\n Ext->>Tab: Read active tab URL and title\n Tab-->>Ext: URL and title\n Ext-->>WS: page_context_response\n WS-->>MCP: page_context_response\n MCP-->>Agent: Structured resource result\n```\n\n---\n\n## Status\n\nThis project has the local WebSocket transport, Chrome extension page context\nand action handling, MCP resources and tools, and local pairing/presence routing\nin place. Safari Web Extension support with full Chrome feature parity is also\nimplemented (ADR 0019), using shared logic from `@brijio/shared`. The\ncurrent working milestone is:\n\n1. A local Chrome extension manually connects to the WebSocket server.\n2. The extension authenticates with a local pairing token and announces browser\n   presence.\n3. The MCP server authenticates with the same token, lists online browser\n   instances, and routes explicit page reads or actions to one browser.\n4. The Safari extension has the same browser capabilities as Chrome, using\n   shared logic and Safari-specific adapters.\n\nFeatures beyond that milestone require an approved ADR before implementation.\n\n---\n\n## MCP Resources And Tools\n\nThe current MCP server exposes page resources:\n\n- `browser://page/current`, named `current-page-context`\n- `browser://page/current/content/{index}`, named `current-page-content`\n\nIt also exposes tools for explicit page reads and discrete browser actions:\n\n- `list_browsers`\n- `read_current_page`\n- `click_element`\n- `fill_input`\n- `fill_editable`\n- `set_checked`\n- `select_options`\n- `submit_form`\n\nResource and tool results use predictable structured responses:\n\n```ts\ntype ToolResult<T> =\n  | { ok: true; data: T }\n  | { ok: false; error: { code: string; message: string } };\n```\n\n---\n\n## Running Brijio\n\n### Option 1: npx (recommended for quick use)\n\n```sh\nnpx @brijio/mcp\n```\n\nThis starts both the WebSocket server and the MCP server with zero config. On startup, auto-generated tokens are printed to the console:\n\n```text\n🚀 Brijio ready!\n\n  WebSocket:    ws://localhost:8787\n  MCP:         http://localhost:8788/mcp\n\n  Pairing Token:    dG9rZW4x  [auto-generated]\n  MCP Auth Token:   dG9rZW4y  [auto-generated]\n```\n\nCopy these tokens — they change on every restart unless you persist them. To persist tokens, create a `.env` file in the working directory:\n\n```sh\nBRIJIO_PAIRING_TOKEN=your-secure-token-here\nMCP_HTTP_AUTH_TOKEN=your-mcp-token-here\n```\n\nOr set environment variables directly:\n\n```sh\nBRIJIO_PAIRING_TOKEN=my-secret npx @brijio/mcp\n```\n\nThe MCP endpoint is then available at `http://localhost:8788/mcp`.\n\n### Option 2: Daemon (recommended for persistent use)\n\nInstall Brijio as a background service that starts on login:\n\n```sh\nnpx @brijio/mcp install\n```\n\nThis creates a LaunchAgent (macOS) or systemd user unit (Linux) that keeps Brijio running. Tokens are generated and stored in `~/.brijio/.env`.\n\n```sh\nnpx @brijio/mcp start     # start the daemon\nnpx @brijio/mcp stop      # stop the daemon\nnpx @brijio/mcp restart   # restart the daemon\nnpx @brijio/mcp status    # check daemon and health status\nnpx @brijio/mcp logs      # view recent logs\nnpx @brijio/mcp logs --live  # stream logs in real-time\nnpx @brijio/mcp uninstall  # remove the daemon service\n```\n\nDaemon commands:\n\n| Command                                | Description                                    |\n| -------------------------------------- | ---------------------------------------------- |\n| `install [--ws-port N] [--mcp-port N]` | Install daemon, generate tokens, start service |\n| `uninstall`                            | Remove service (preserves config and logs)     |\n| `start`                                | Start the daemon                               |\n| `stop`                                 | Stop the daemon                                |\n| `restart`                              | Restart the daemon                             |\n| `status`                               | Show daemon state and health check results     |\n| `logs [--lines N] [--live]`            | View or stream daemon logs                     |\n\nConfig is stored in `~/.brijio/.env`. To fully remove all Brijio daemon data: `rm -rf ~/.brijio`.\n\n### Option 3: Docker\n\n```sh\ndocker run -p 8787:8787 -p 8788:8788 \\\n  -e BRIJIO_PAIRING_TOKEN=my-pairing-token \\\n  -e MCP_HTTP_AUTH_TOKEN=my-mcp-token \\\n  brijio/mcp\n```\n\nOr with Docker Compose — copy `.env.example` to `.env`, fill in your tokens, then:\n\n```sh\ndocker compose up\n```\n\nBoth ports must be exposed: **8787** (WebSocket relay) and **8788** (MCP HTTP server). The Docker image bundles both services in a single container — no need to run separate images.\n\n### Connecting Your Browser\n\n1. Install the [Brijio Chrome extension](https://github.com/brijio/mcp)\n2. Click the Brijio icon in your toolbar\n3. Enter the WebSocket URL (default: `ws://localhost:8787`) and the pairing token\n4. Click **Connect**\n\n### Connecting Your AI Agent\n\nConfigure your MCP client (Claude Desktop, Hermes, etc.) to connect to the MCP server:\n\n```json\n{\n  \"mcpServers\": {\n    \"brijio\": {\n      \"type\": \"streamableHttp\",\n      \"url\": \"http://localhost:8788/mcp\",\n      \"headers\": {\n        \"Authorization\": \"Bearer my-mcp-token\"\n      }\n    }\n  }\n}\n```\n\n### Environment Variables\n\n| Variable                    | Default               | Description                       |\n| --------------------------- | --------------------- | --------------------------------- |\n| `WEBSOCKET_HOST`            | `0.0.0.0`             | WebSocket server bind address     |\n| `WEBSOCKET_PORT`            | `8787`                | WebSocket server port             |\n| `BRIJIO_PAIRING_TOKEN`      | _auto-generated_      | Token for extension ↔ server auth |\n| `MCP_HTTP_HOST`             | `0.0.0.0`             | MCP server bind address           |\n| `MCP_HTTP_PORT`             | `8788`                | MCP server port                   |\n| `MCP_HTTP_PATH`             | `/mcp`                | MCP server path                   |\n| `MCP_HTTP_AUTH_TOKEN`       | _auto-generated_      | Bearer token for MCP clients      |\n| `BRIJIO_WS_URL`             | `ws://127.0.0.1:8787` | WS URL for MCP → relay connection |\n| `BRIJIO_REQUEST_TIMEOUT_MS` | `5000`                | Timeout for forwarded requests    |\n\nAuto-generated tokens are ephemeral — they change on restart. For production or persistent setups, always set `BRIJIO_PAIRING_TOKEN` and `MCP_HTTP_AUTH_TOKEN` explicitly.\n\nFor Tailscale:\n\n```sh\nMCP_HTTP_HOST=0.0.0.0\n```\n\nNo additional host allowlists are needed — auth tokens are the security boundary, not IP allowlists. See the security model below for details.\n\n---\n\n## Local Development\n\n### Prerequisites\n\n- **Node.js** ≥ 20\n- **pnpm** ≥ 10 (`corepack enable` or `npm i -g pnpm`)\n\n### Build\n\nBuild all workspace packages (shared package, WebSocket server, MCP server, and both browser extensions):\n\n```sh\npnpm install\npnpm build\n```\n\nTo build only the server packages:\n\n```sh\npnpm --filter @brijio/websocket build\npnpm --filter @brijio/mcp build\n```\n\n### Install & Start\n\nCopy the environment template and generate tokens:\n\n```sh\ncp .env.example .env\npnpm run token     # generates BRIJIO_PAIRING_TOKEN\n```\n\nEdit `.env` to set `BRIJIO_PAIRING_TOKEN` and `MCP_HTTP_AUTH_TOKEN` with your own values.\n\nStart both servers with hot-reload:\n\n```sh\npnpm dev\n```\n\nOr start individual servers:\n\n```sh\npnpm --filter @brijio/websocket dev   # WebSocket relay on ws://0.0.0.0:8787\npnpm --filter @brijio/mcp dev         # MCP server on http://0.0.0.0:8788/mcp\n```\n\nFor a production-style build + run:\n\n```sh\npnpm build\nnode servers/mcp/dist/bin/brijio.js\n```\n\nOr use the daemon lifecycle commands from source:\n\n```sh\npnpm brijio install   # install as a background service\npnpm brijio start      # start the daemon\npnpm brijio status     # check daemon health\n```\n\nDocker-based local development:\n\n```sh\ndocker compose --profile runtime up --build\n```\n\nThe runtime profile includes a demo page served over HTTP:\n\n```text\nhttp://127.0.0.1:${TEST_PAGE_PORT:-8080}/\n```\n\nConfigure the same pairing token in the Chrome extension setup page along\nwith the local WebSocket URL.\n\nGenerate a separate MCP HTTP bearer token and set it as\n`MCP_HTTP_AUTH_TOKEN`. MCP clients connect to:\n\n```text\nhttp://127.0.0.1:${MCP_HTTP_PORT:-8788}${MCP_HTTP_PATH:-/mcp}\n```\n\n### Testing The WebSocket Server With A CLI\n\nStart the WebSocket server:\n\n```sh\npnpm --filter @brijio/websocket dev\n```\n\nIn another terminal, connect with `wscat`:\n\n```sh\npnpm dlx wscat -c ws://127.0.0.1:8787\n```\n\nSend an auth message first:\n\n```json\n{\n  \"type\": \"message\",\n  \"id\": \"auth-1\",\n  \"payload\": {\n    \"type\": \"auth\",\n    \"role\": \"mcp\",\n    \"token\": \"***\"\n  }\n}\n```\n\nThen send a valid MCP-scoped request:\n\n```json\n{ \"type\": \"message\", \"id\": \"cli-1\", \"payload\": { \"type\": \"list_browsers\" } }\n```\n\n> **Compatibility:** `BRIJIO_PAIRING_TOKEN`, `BRIJIO_TOKEN`, `BRIJIO_WEBSOCKET_URL`, `BRIJIO_WS_URL`, `BRIJIO_REQUEST_TIMEOUT_MS`, and `BRIJIO_BROWSER_INSTANCE_ID` remain accepted as backward-compatible aliases during the transition window. `BRIJIO_BROWSER_INSTANCE_ID` is optional; when set, MCP tools target that browser by default.\n\n---\n\n## Repository Layout\n\n```text\n/package.json\n/pnpm-workspace.yaml\n/packages\n /shared\n /src\n protocol.ts\n page-context.ts\n page-content.ts\n background-controller.ts\n content-handler.ts\n timers.ts\n package.json\n/servers\n /websocket\n /src\n index.ts\n sessions.ts\n messages.ts\n package.json\n /mcp\n /src\n index.ts\n page-context.ts\n websocket-client.ts\n package.json\n/clients\n /extensions\n /chrome\n /safari\n /firefox\n /apps\n/docs\n /architecture\n ARCHITECTURE.md\n /decisions\n /security\n /project\n```\n\n---\n\n## Verify in 2 Minutes\n\nRun `brijio demo` to start a self-contained demo server that exercises every Brijio MCP tool — no Docker, no browser extension, no external dependencies required.\n\n```sh\nnpx brijio demo              # starts WS (8787) + MCP (8788) + demo page (8789)\n```\n\nOpen the printed demo URL (default: `http://localhost:8789/`) in any browser. The page contains:\n\n- **Story passages** — Sherlock Holmes text that exceeds 128 KiB, forcing `read_current_page` to paginate across multiple chunks\n- **Structured data tables** — character profiles, timelines, deduction references, and cross-story indexes\n- **Comprehensive form controls** — text, email, password, number, date, textarea, contenteditable, checkboxes, radios, single/multi-selects, disabled controls, and submit/reset buttons\n- **Self-verifying submission** — form posts via GET parameters; `#results` shows ✅/❌ for each answer\n- **Dynamic content** — live timestamp and auto-incrementing counter for polling tests\n\n### Quick Checks\n\n| MCP Tool                 | Test                                   | Expected Result                                      |\n| ------------------------ | -------------------------------------- | ---------------------------------------------------- |\n| `read_current_page`      | Read the page                          | Multiple chunks; story text present in early chunks  |\n| `fill_input`             | Fill `surname` with \"Stoner\"           | Field shows \"Stoner\"                                 |\n| `form_action` (checkbox) | Check `chk-ventilator`                 | Checkbox checked                                     |\n| `form_action` (radio)    | Select `radio-snake`                   | Radio selected                                       |\n| `form_action` (select)   | Select `calcutta` in `location-select` | Dropdown shows \"Calcutta, India\"                     |\n| `click_element`          | Click `btn-prefill`                    | All fields populate with correct answers             |\n| `click_element`          | Click `btn-submit`                     | URL updates with GET params; results section appears |\n\nFor the full checklist, see [`clients/test-page/smoke-test.md`](clients/test-page/smoke-test.md).\n\n---\n\n## License\n\nBrijio source code is licensed under the GNU Affero General Public\nLicense v3.0 (AGPLv3). See [LICENSE](LICENSE).\n\nCommercial licensing is available for organizations that require alternative\nterms. See [COMMERCIAL-LICENSING.md](COMMERCIAL-LICENSING.md).\n\nContributions are accepted under the project license. Contributors retain\ncopyright in their contributions. See [CONTRIBUTING.md](CONTRIBUTING.md).\n",
  "bytes": 15959,
  "sha": "0d867b1ed6906565a6ccdbfbec6cd6d9f30a709deba06053246a561398ac639c",
  "repo_slug": "redvex/brijio",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/okf_redvex_brijio_openwiki_index_md_d8c6df11/readme"
}