Skip to main content
Glama
README.md
# webverb-mcp

[![License: MIT](https://img.shields.io/badge/license-MIT-green?style=flat-square)](LICENSE) ![Python 3.13+](https://img.shields.io/badge/python-3.13%2B-blue?style=flat-square) ![MCP](https://img.shields.io/badge/MCP-stdio%20server-8A2BE2?style=flat-square)

**Your agent, working in the sites you're already logged into.**

81 typed verbs across 13 sites. Typed fields, not HTML soup.

> **New here?** [**What webverb is, in pictures →**](https://claude.ai/code/artifact/6133e479-bd24-40ae-9379-03abc3a3e602)
> A two-minute visual explainer: the problem it solves, how you use it, and where it runs.

## Quick start

```bash
claude plugin marketplace add jiancui-research/webverb-mcp-python-public-beta
claude plugin install webverb@webverb-marketplace
```

The first call launches a **second, separate Chrome** and asks you to sign in there once.
Not the Chrome you use every day — a dedicated one, with its own profile.

## How it gets access

```mermaid
flowchart LR
    A["everyday Chrome · untouched<br/>~/Library/Application Support/Google/Chrome"]
    you(("you")) -->|"sign in once"| B["debug Chrome · :9222<br/>~/chrome-debug-profile"]
    wv["webverb"] --> B
    B --> S(["gmail · reddit · maps …"])
```

Two Chromes, two profiles, nothing shared. webverb never sees a password; it attaches to
the browser you signed into. (`C:\chrome-debug-profile` on Windows.)

What that costs:

- **`:9222` has no auth.** Any local process that reaches it drives that browser.
- **The profile is a real cookie jar** — reading that directory gets your sessions.
- **The agent acts as you.** 33 of the 81 verbs change account state.
- **Results leave the machine**, forwarded to your model.

Chrome 136+ refuses `--remote-debugging-port` on your default profile, which is why this
needs its own. Full threat model: [SECURITY.md](SECURITY.md).

<details>
<summary>Codex · Copilot CLI · any MCP host</summary>

```bash
git clone https://github.com/jiancui-research/webverb-mcp-python-public-beta
cd webverb-mcp-python-public-beta && uv sync
```

```jsonc
{ "mcpServers": { "web-verbs": {
    "command": "uv",
    "args": ["--directory", "/abs/path/to/repo", "run", "python", "-m", "webverb_mcp"] } } }
```

Use an **absolute** path, and raise the tool-call timeout to ~300s — a verb that scrolls a
lazy-loading feed can legitimately take minutes.

</details>

## Then just ask

- *"Summarise the top comments on my Reddit feed."*
- *"Search my Gmail for the Acme invoice and start a reply draft."*
- *"What's in my Amazon cart, and what did I order last month?"*
- *"List my Overleaf projects and show me the intro of the ICLR one."*

Under *"summarise the top comments on my Reddit feed"*, that's three calls:

```console
› search_verb(query="reddit home feed")
    reddit_com/feed              score 3.0
    1point3acres_com/feed        score 2.0

› run_verb("reddit_com/feed", {"max_posts": 3})
     715 up  505 comments  r/LocalLLaMA     "The All Spark" Cluster: Upgrading from 16 -
       — up    0 comments  r/u_Amazon_Official Healthcare can be a real pain for a medical
      35 up   45 comments  r/PiCodingAgent  Subagent extensions

› run_verb("reddit_com/post_comments", {"post_url": "…/r/LocalLLaMA/comments/1…"})
      1 ▲  WithoutReason1729  Your post is getting popular and we just featured it
    241 ▲  johnfkngzoidberg   That's like $150k worth of hardware. Wtf.
    192 ▲  Kurcide            About $200k worth at today's prices after the switch
```

Verbatim from a real run. Two things it shows: the feed hands you the `post_url` the
comments verb takes, so a follow-up is one more call — and the promoted post reports
`—` rather than a score, because it's flagged `is_promoted` instead of being silently
dropped.

## What's covered

| Site | Verbs | | Site | Verbs |
| --- | :-: | --- | --- | :-: |
| amazon.com | 11 | | overleaf.com | 6 |
| docs.google.com | 10 | | reddit.com | 4 |
| drive.google.com | 10 | | x.com | 4 |
| mail.google.com | 10 | | linkedin.com | 4 |
| google.com Maps | 8 | | rednote.com | 4 |
| google.com Flights + auth | 2 | | 1point3acres.com | 4 |
| hotcrp.com | 4 | | | |

```bash
uv run python -m webverb_mcp.registry    # list everything
uv run inspect_verb.py <verb>            # one verb's exact arguments
```

## Missing a site? Build the verb

A verb is one file in one folder under `verbs/<site>/<action>/` — the registry finds it at
boot, no server change, at whatever depth you file it. You don't write it from scratch;
four commands hand your agent the process:

| Command | Use it to |
| --- | --- |
| `/webverb:write-verb <site or action>` | Add a verb for something nothing covers yet |
| `/webverb:fix-verb <verb or symptom>` | Repair one that broke when a site redesigned |
| `/webverb:verify-verbs [verb or site]` | Prove verbs work against real values, not "non-empty" |
| `/webverb:verb-contract [topic]` | Look up the exact rule instead of guessing |

Keep your verbs outside the install so updates can't remove them:

```bash
export WEBVERB_VERBS_DIR=~/my-verbs
```

### After you build one

```bash
uv run python -m webverb_mcp.lint        # contract check — exit 0 = clean
uv run python -m webverb_mcp.registry    # your verb should appear, 0 skipped
```

Then, in order:

1. **Reconnect with `/mcp`.** The running server built its registry at boot, so it cannot
   see a verb you just added. This is the single most common "why isn't my verb showing
   up" — the file is fine, the server is stale.
2. **Verify it lives:** `/webverb:verify-verbs <your verb>`. Registering is not working;
   a verb can register cleanly and still return wrong fields.
3. **Share it, if it's a public site:** a verb is one file, so a pull request is small.
   See [CONTRIBUTING](CONTRIBUTING.md).

If the verb doesn't appear at all, the usual cause is a second `.py` in its folder — the
registry silently drops those, which is what `lint` catches.

## How it works

```mermaid
flowchart LR
    A[Your agent] -->|"search_verb('reddit feed')"| B[webverb MCP]
    A -->|"run_verb(id, args)"| B
    B --> C[(81 verbs)]
    B -->|CDP :9222| D[Your signed-in Chrome]
    D --> E([reddit · gmail · drive<br/>amazon · linkedin …])
    E -->|typed dataclass| A
```

Two tools, not one per verb, so context cost stays flat whether you have 4 verbs or 400.
`search_verb` finds the right one and returns its schema; `run_verb` executes it.

Two properties you'll notice in practice:

- **Cheap.** A verb returns a few hundred bytes where an accessibility snapshot of the same
  page runs 40,000+ characters.
- **Fails loudly.** When a site redesigns, verbs raise instead of returning an
  empty-but-successful result — so you get an error, not a confidently wrong summary.

Eleven `raw_browser_*` primitives are there for whatever no verb covers yet, and for
diagnosing a verb that broke. They're named and described as a fallback so your agent
reaches for `search_verb` first. If you'd rather they not exist at all:

```bash
export WEBVERB_RAW_TOOLS=0     # leaves only search_verb and run_verb
```

Naming and descriptions are steering, and a model can ignore steering. That variable is
the only setting that makes raw page-driving impossible.

## Before you rely on it

> [!IMPORTANT]
> **Public beta.** Verbs act in your real accounts, and some sites prohibit automated
> access. Keep volumes modest and stop if a site starts refusing requests.

- **Most verbs read; 33 of 81 write.** Reading is the default, but the library includes actions
  that change state — Gmail drafts, Drive moves and trashing, Amazon cart edits, Overleaf
  project creation and trashing, Maps list edits, HotCRP review bids. Check a verb's name and
  `inspect_verb.py` before running it on an account you care about.
- **A running server caches the registry at boot.** After adding a verb or pulling, run
  `/mcp` to reconnect, or you'll keep seeing the old set.
- Chrome 136+ ignores `--remote-debugging-port` on the default profile, which is why a
  dedicated one is required.

[HotCRP quick start](docs/hotcrp-quickstart.md) · [Roadmap](ROADMAP.md) · [Troubleshooting](docs/troubleshooting.md) · [Contributing](CONTRIBUTING.md) · [Security](SECURITY.md) · MIT

Maintenance

ActivityActive
ResponsivenessNo issues