Metadata-Version: 2.4
Name: agent-viewer-mcp
Version: 0.2.0
Summary: MCP server + HTTP bridge that give AI agents a visible browser: a virtual cursor glides and clicks on a real Chromium window.
Author: fatunkaz
License: MIT License
        
        Copyright (c) 2026 fatunkaz
        
        Permission is hereby granted, free of charge, to any person obtaining a copy
        of this software and associated documentation files (the "Software"), to deal
        in the Software without restriction, including without limitation the rights
        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
        copies of the Software, and to permit persons to whom the Software is
        furnished to do so, subject to the following conditions:
        
        The above copyright notice and this permission notice shall be included in all
        copies or substantial portions of the Software.
        
        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
        SOFTWARE.
        
Project-URL: Homepage, https://github.com/fatunkaz/agent-viewer
Keywords: mcp,model-context-protocol,automation,playwright,browser,agent,cline,rpa
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Software Development :: Testing
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: flask>=3.0
Requires-Dist: mcp>=1.10
Requires-Dist: playwright>=1.40
Dynamic: license-file

# agent-viewer

> Give your AI agent a **visible** browser. `agent-viewer` is an
> [MCP](https://modelcontextprotocol.io) server (plus a standalone HTTP bridge)
> that lets a model drive a real Chromium window — and you can **watch** it work,
> because a virtual cursor glides to each target and clicks.

[![Python](https://img.shields.io/badge/python-3.10%2B-blue.svg)](https://www.python.org/)
[![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE)
[![MCP](https://img.shields.io/badge/MCP-server-6E56CF.svg)](https://modelcontextprotocol.io)
[![Playwright](https://img.shields.io/badge/driven%20by-Playwright-2EAD33.svg)](https://playwright.dev/python/)

---

## Features

- **MCP server** — Cline / Claude Desktop / Cursor / any MCP host gets
  `browser_*` tools and can drive the browser on its own.
- **Visible cursor overlay** — a red dot glides to each target with a click ripple.
- **Standalone HTTP bridge** — the same engine over `http://127.0.0.1:8765`, with a
  small CLI client (`av`) for scripts or manual use.
- **Survives navigation** — the overlay is injected on every page via an init script.
- **Image-map aware** — can click `<area>` regions of HTML image maps.
- **Headful or headless**, configurable animation speed, idle auto-shutdown.

## Requirements

- Python 3.10+
- [Playwright](https://playwright.dev/python/) (Chromium is fetched automatically)

## Install

```bash
pip install agent-viewer-mcp
python -m playwright install chromium
```

Or from source:

```bash
git clone https://github.com/fatunkaz/agent-viewer.git
cd agent-viewer
pip install -r requirements.txt
python -m playwright install chromium
```

## Use it from your AI agent (MCP)

Add the server to your MCP host. For **Cline** (`~/.cline/mcp.json`, or the MCP
panel in the IDE):

```json
{
  "mcpServers": {
    "agent-viewer": {
      "command": "uvx",
      "args": ["--from", "agent-viewer-mcp", "agent-viewer-mcp"],
      "disabled": false
    }
  }
}
```

Now the model can call `browser_goto`, `browser_click`, `browser_type`,
`browser_press`, `browser_read`, `browser_eval`, `browser_screenshot` by itself.
Full guide (other hosts, env vars, troubleshooting): [`docs/MCP.md`](docs/MCP.md).

## Use it standalone (HTTP bridge + CLI)

**Terminal 1 — start the bridge (opens a browser window):**

```bash
python agent_viewer.py            # or: python -m agent_viewer.server
```

**Terminal 2 — drive it with the CLI:**

```bash
python av.py goto https://example.com
python av.py click "a[href='/about']"
python av.py type "#search" "hello" --submit
python av.py read "#main"
python av.py shot home
python av.py quit
```

The window stays open between commands, so you can watch each action happen.

## How it works

```
  AI host (Cline/Claude)        agent-viewer (this project)         the web
  ---------------------         ---------------------------         -------
   MCP tool call  ------>   MCP server  (mcp_server.py)   \
                             HTTP bridge (server.py)  ------+-->  Chromium
   av CLI / curl  ------>                                  /      (visible)
                                        |
                                        v
                                 BrowserAgent (browser.py)
                                        |  inject CURSOR_JS on every page
                                        v
                                 move virtual cursor -> real click
```

Both entry points share the same engine, `BrowserAgent` (`browser.py`). The
virtual cursor is a DOM element injected into every page (`__ac_move` /
`__ac_ripple`); real clicks use `page.mouse.click` at the element center. For
`<area>` elements the center is computed from the image-map polygon and scaled to
the rendered image.

More details: [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md) ·
[`docs/MCP.md`](docs/MCP.md).

## HTTP API

| Method | Path          | Body / query                        | Purpose                                           |
| ------ | ------------- | ----------------------------------- | ------------------------------------------------- |
| GET    | `/health`     | —                                   | status + current URL                              |
| POST   | `/goto`       | `{url, wait_until?, timeout?}`      | navigate (tolerates pages that never fire `load`) |
| POST   | `/click`      | `{selector, speed?}`                | move cursor and click (also `<area>`)             |
| POST   | `/type`       | `{selector, text, speed?, submit?}` | focus + type character by character               |
| POST   | `/press`      | `{key, selector?}`                  | press a key                                       |
| POST   | `/eval`       | `{expr}` or `{fn, arg}`             | run JS in the page                                |
| GET    | `/read`       | `?selector=`                        | innerText of the page or an element               |
| GET    | `/screenshot` | `?name=`                            | save a PNG, return path + base64                  |
| POST   | `/quit`       | —                                   | close the browser and the server                  |

Full reference with `curl` examples: [`docs/API.md`](docs/API.md).

## Server options

```bash
python agent_viewer.py --port 8765 --speed 1.0 --headless --idle 600
```

| Option                | Default       | Description                                              |
| --------------------- | ------------- | -------------------------------------------------------- |
| `--port`              | `8765`        | HTTP port                                                |
| `--speed`             | `1.0`         | cursor animation speed multiplier                        |
| `--width`, `--height` | `1280`, `800` | window / viewport size                                   |
| `--headless`          | off           | run without a visible window                             |
| `--idle N`            | `0`           | auto-quit after `N` seconds without commands (`0` = off) |
| `--url`               | `about:blank` | initial URL                                              |

The bridge also shuts itself down if you close the browser window manually.

## Project layout

```
agent-viewer/
|- agent_viewer/            # the package
|  |- browser.py            # shared Playwright engine (visible cursor)
|  |- mcp_server.py         # MCP server -> browser_* tools
|  |- server.py             # Flask HTTP bridge (standalone mode)
|  |- client.py             # CLI client (`av`)
|  |- js.py                 # injected cursor / center JS
|- agent_viewer.py          # compatibility entry point
|- av.py                    # compatibility entry point
|- docs/
|  |- MCP.md                # connect to Cline and other MCP hosts
|  |- API.md                # HTTP API reference
|  |- ARCHITECTURE.md       # how it works
|- requirements.txt
|- pyproject.toml
|- LICENSE
```

## Disclaimer

This project is an **educational / RPA demonstration** of a _visible_ browser
automation agent. It is **site-agnostic** and ships with no third-party content.
Use it responsibly:

- Respect the Terms of Service and `robots.txt` of any website you automate.
- Do **not** use it to violate a site's rules, game leaderboards, or scrape
  content you are not allowed to copy.
- The `/eval` endpoint executes arbitrary JavaScript in the target page, and the
  server binds to `127.0.0.1` only — never expose it to a network.

## License

[MIT](LICENSE) (c) 2026 fatunkaz
