Add optional stateless MCP server for the real browser

Expose a conservative browser-cli tool surface to MCP hosts without
duplicating browser-control logic: every tool is a thin adapter over the
existing Python SDK, and each call builds a fresh BrowserCLI so the real
browser stays the only owner of tab and navigation state.

The MCP process resolves BROWSER_CLI_PROFILE, BROWSER_CLI_REMOTE, and
BROWSER_CLI_KEY explicitly instead of passing None down, so a pinned server
targets one browser rather than fanning listing calls out across every
connected browser. Explicit tool arguments still win.

Tool names keep a browser_ prefix for hosts that expose raw MCP names, while
BROWSER_CLI_MCP_TOOL_PREFIX lets hosts that already namespace by server drop
it and avoid names like browser_cli_testing_browser_tabs_list.

JavaScript evaluation, raw commands, storage writes, and session import stay
unexposed, and Streamable HTTP refuses non-loopback binds because the endpoint
has no authentication of its own; remote browsers go through browser-cli's
authenticated remote transport instead.

MCP stays an optional extra, so normal installs are unaffected.
This commit is contained in:
2026-08-09 20:37:47 +02:00
parent 7b4d96845d
commit bd2a18baba
8 changed files with 1292 additions and 2 deletions
+83
View File
@@ -70,6 +70,11 @@ For better remote-response compression, install the optional `fast` extra:
uv tool install "real-browser-cli[fast]"
```
To expose the conservative MCP tool surface, install the optional `mcp` extra:
```sh
uv tool install "real-browser-cli[mcp]"
```
To upgrade later:
```sh
@@ -141,6 +146,84 @@ browser-cli/
---
## Stateless MCP server
The optional MCP adapter exposes a small, typed subset of the Python SDK for
MCP hosts such as Claude Desktop, Claude Code, Cursor, or VS Code. It controls
the same real browser; it does not launch a headless browser or duplicate the
browser command implementation.
Install and run the local stdio server:
```sh
uv tool install "real-browser-cli[mcp]"
browser-cli-mcp
```
Example MCP host configuration:
```json
{
"mcpServers": {
"browser-cli": {
"command": "browser-cli-mcp"
}
}
}
```
The server is stateless at the MCP layer. Every tool call creates a fresh
`BrowserCLI` SDK client, and browser state remains in the real browser. Pass
`browser`, `remote`, and `key` on a tool call when a specific local profile or
authenticated browser-cli remote is required.
Available tools:
- `browser_tabs_list`, `browser_tabs_open`, `browser_tabs_close`
- `browser_navigate`, `browser_page_info`
- `browser_extract_text`, `browser_extract_markdown`
- `browser_dom_query`, `browser_dom_click`, `browser_dom_type`
- `browser_screenshot`
Generic JavaScript evaluation, raw browser commands, storage writes, and
session import are intentionally not exposed.
### Pinning one browser and naming tools
Set `BROWSER_CLI_PROFILE` to pin every call from an MCP server to one browser,
so tools do not have to pass `browser` and listing tools do not fan out across
all connected browsers:
```json
{
"mcpServers": {
"browser-cli-testing": {
"command": "browser-cli-mcp",
"env": {
"BROWSER_CLI_PROFILE": "testing",
"BROWSER_CLI_MCP_TOOL_PREFIX": ""
}
}
}
}
```
`BROWSER_CLI_REMOTE` and `BROWSER_CLI_KEY` pin an authenticated remote the same
way. Explicit `browser`, `remote`, and `key` tool arguments still win.
Tool names carry a `browser_` prefix by default so they stay unambiguous in
hosts that expose raw MCP tool names. Hosts that already prefix tools with the
server name produce stutter such as `browser_cli_testing_browser_tabs_list`;
setting `BROWSER_CLI_MCP_TOOL_PREFIX` to an empty string drops the built-in
prefix and yields `browser_cli_testing_tabs_list`. Any other value replaces the
prefix.
For local development and testing, Streamable HTTP is also available:
```sh
browser-cli-mcp --transport streamable-http --port 8000
# endpoint: http://127.0.0.1:8000/mcp
```
HTTP uses stateless JSON responses and intentionally refuses non-loopback bind
addresses because this MCP endpoint has no independent authentication. For a
browser on another machine, keep MCP local and pass an authenticated
browser-cli `remote` target to each tool call.
---
## CLI reference
During source development, commands are usually run as `uv run browser-cli [--browser ALIAS] <command>`. After tool installation, use `browser-cli ...` directly. Add `--remote HOST[:PORT]` and optionally `--key PATH` to target a browser exposed by `browser-cli serve`.