@humanjs/mcp 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +241 -0
- package/dist/index.cjs +1102 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +2 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1099 -0
- package/dist/index.js.map +1 -0
- package/package.json +75 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Gonzalo Muñoz
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
# @humanjs/mcp
|
|
2
|
+
|
|
3
|
+
<p>
|
|
4
|
+
<a href="https://www.npmjs.com/package/@humanjs/mcp"><img alt="npm" src="https://img.shields.io/npm/v/@humanjs/mcp"></a>
|
|
5
|
+
<a href="https://www.npmjs.com/package/@humanjs/mcp"><img alt="downloads" src="https://img.shields.io/npm/dt/@humanjs/mcp"></a>
|
|
6
|
+
<a href="https://github.com/totigm/humanjs"><img alt="GitHub" src="https://img.shields.io/badge/GitHub-totigm%2Fhumanjs-181717?logo=github"></a>
|
|
7
|
+
<a href="https://github.com/totigm/humanjs/actions/workflows/ci.yml"><img alt="CI" src="https://github.com/totigm/humanjs/actions/workflows/ci.yml/badge.svg"></a>
|
|
8
|
+
<a href="https://github.com/totigm/humanjs/blob/main/LICENSE"><img alt="license" src="https://img.shields.io/npm/l/@humanjs/mcp"></a>
|
|
9
|
+
<a href="https://humanjs.dev"><img alt="docs" src="https://img.shields.io/badge/docs-humanjs.dev-emerald"></a>
|
|
10
|
+
</p>
|
|
11
|
+
|
|
12
|
+
Model Context Protocol server for [HumanJS](https://humanjs.dev) — let AI agents drive a Playwright browser with **humanized** motion, typing, and reading dwell.
|
|
13
|
+
|
|
14
|
+
It's Playwright-MCP-but-humanized: the same stdio protocol every desktop AI client speaks, except every action moves like a person and the cursor is visible — so live demos and recordings look real, not robotic.
|
|
15
|
+
|
|
16
|
+
> **Audience:** AI agent builders, QA engineers, and demo/tutorial creators. HumanJS is **not** a scraping, captcha-bypass, or "undetectable automation" tool — see the [non-goals](https://humanjs.dev).
|
|
17
|
+
|
|
18
|
+
## Quick start
|
|
19
|
+
|
|
20
|
+
Add it to your MCP client config. The server runs over stdio via `npx`, so there's nothing to install globally.
|
|
21
|
+
|
|
22
|
+
**Claude Desktop** (`claude_desktop_config.json`), **Claude Code** (`~/.claude.json` or project `.mcp.json`), **Cursor** (`.cursor/mcp.json`), **Codex**, **Cline**, etc. all use the same shape:
|
|
23
|
+
|
|
24
|
+
```jsonc
|
|
25
|
+
{
|
|
26
|
+
"mcpServers": {
|
|
27
|
+
"humanjs": {
|
|
28
|
+
"command": "npx",
|
|
29
|
+
"args": ["-y", "@humanjs/mcp"],
|
|
30
|
+
"env": { "HUMANJS_PERSONALITY": "careful" }
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Restart the client, then ask it to do something in a browser:
|
|
37
|
+
|
|
38
|
+
> "Use HumanJS to open example.com, search for 'docs', and screenshot the result."
|
|
39
|
+
|
|
40
|
+
The first browser action launches a visible Chromium window with the humanized cursor overlay.
|
|
41
|
+
|
|
42
|
+
> **Requirements:** Node ≥ 20. The `playwright` npm package is bundled as a dependency, and the **Chromium browser binary downloads automatically** on first launch if it's missing (~150MB, one time). To disable that auto-download in locked-down environments, set `HUMANJS_AUTO_INSTALL=false` and install manually with `npx playwright install chromium`.
|
|
43
|
+
|
|
44
|
+
### One-command install
|
|
45
|
+
|
|
46
|
+
Some clients can register the server for you, no manual JSON:
|
|
47
|
+
|
|
48
|
+
**Claude Code:**
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
claude mcp add humanjs --env HUMANJS_PERSONALITY=careful -- npx -y @humanjs/mcp
|
|
52
|
+
# add --scope user to install it globally (all projects)
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
**Cursor** — one click:
|
|
56
|
+
|
|
57
|
+
[](https://cursor.com/install-mcp?name=humanjs&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyIteSIsIkBodW1hbmpzL21jcCJdfQ==)
|
|
58
|
+
|
|
59
|
+
The `config` payload is base64 of `{"command":"npx","args":["-y","@humanjs/mcp"]}` — regenerate it via [cursor.com/docs/mcp/install-links](https://cursor.com/docs/mcp/install-links) if you change the command or add env vars.
|
|
60
|
+
|
|
61
|
+
## Environment variables
|
|
62
|
+
|
|
63
|
+
| Variable | Values | Default | Purpose |
|
|
64
|
+
|---|---|---|---|
|
|
65
|
+
| `HUMANJS_PERSONALITY` | `careful` \| `fast` \| `distracted` \| `precise` | `careful` | Default personality for every session. |
|
|
66
|
+
| `HUMANJS_SPEED` | `human` \| `fast` \| `instant` | `human` | Humanization pace. `human` = full realistic motion; `fast` = humanized but quick; `instant` = no humanized motion. Changes how long each action *executes*, not the wait between actions. |
|
|
67
|
+
| `HUMANJS_HEADLESS` | `true` \| `false` | `false` | Headless browser. Default is visible — the point of the MCP. |
|
|
68
|
+
| `HUMANJS_OUTPUT_DIR` | path | server's CWD | Where screenshots and recordings are written. |
|
|
69
|
+
| `HUMANJS_VIEWPORT` | `WIDTHxHEIGHT` | `1440x900` | Default viewport for new sessions. Bump to `1920x1080` for crisper recordings. |
|
|
70
|
+
| `HUMANJS_AUTO_INSTALL` | `true` \| `false` | `true` | Auto-download the Chromium binary on first launch if missing. Set `false` to require a manual `npx playwright install chromium`. |
|
|
71
|
+
| `HUMANJS_PERSIST` | `true` \| `false` | `false` | Persist a profile across runs (logins/cookies survive). Uses `~/.humanjs/profile` unless `HUMANJS_USER_DATA_DIR` is set. See [Browser modes](#browser-modes). |
|
|
72
|
+
| `HUMANJS_USER_DATA_DIR` | path | — | Explicit persistent profile directory (implies persistence). |
|
|
73
|
+
| `HUMANJS_CDP_URL` | URL | — | Attach to an already-running browser over CDP (e.g. `http://localhost:9222`) and use its real logins/tabs. |
|
|
74
|
+
| `HUMANJS_CHANNEL` | `chrome` \| `msedge` \| … | bundled Chromium | Launch an installed browser's binary instead of bundled Chromium. Does **not** by itself reuse your profile/logins. |
|
|
75
|
+
|
|
76
|
+
All of these go in the `env` block of the client config from [Quick start](#quick-start) — for example, a bigger default viewport and headless mode:
|
|
77
|
+
|
|
78
|
+
```jsonc
|
|
79
|
+
{
|
|
80
|
+
"mcpServers": {
|
|
81
|
+
"humanjs": {
|
|
82
|
+
"command": "npx",
|
|
83
|
+
"args": ["-y", "@humanjs/mcp"],
|
|
84
|
+
"env": {
|
|
85
|
+
"HUMANJS_PERSONALITY": "careful",
|
|
86
|
+
"HUMANJS_VIEWPORT": "1920x1080",
|
|
87
|
+
"HUMANJS_HEADLESS": "false"
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Changes to `env` take effect on the next client restart. To resize without restarting, use the `human_set_viewport` tool mid-session.
|
|
95
|
+
|
|
96
|
+
## Tools
|
|
97
|
+
|
|
98
|
+
**Primitives** — the humanized actions:
|
|
99
|
+
|
|
100
|
+
| Tool | What it does |
|
|
101
|
+
|---|---|
|
|
102
|
+
| `human_goto` | Navigate to a URL |
|
|
103
|
+
| `human_click` | Click (selector **or** x/y coordinates) |
|
|
104
|
+
| `human_rightClick` | Context-menu click (selector or coordinates) |
|
|
105
|
+
| `human_hover` | Hover an element (tooltips, dropdowns) |
|
|
106
|
+
| `human_move` | Move the cursor (selector or coordinates) |
|
|
107
|
+
| `human_drag` | Drag between two points (each a selector or coordinates) |
|
|
108
|
+
| `human_type` | Type with realistic per-key rhythm |
|
|
109
|
+
| `human_paste` | Insert text in one shot (Cmd-V semantic) |
|
|
110
|
+
| `human_press` | Press a key or chord (`Enter`, `Mod+S`, …) |
|
|
111
|
+
| `human_scroll` | Scroll the page or a container |
|
|
112
|
+
| `human_read` | Dwell as if reading (visible cursor scan) |
|
|
113
|
+
|
|
114
|
+
Click / rightClick / move / drag take a **selector or raw x/y coordinates** — coordinates are the fallback for controls with no clean selector (icon-only buttons, canvas, SVG) that the agent can see in a screenshot.
|
|
115
|
+
|
|
116
|
+
**Inspection** — read page state so the agent isn't flying blind:
|
|
117
|
+
|
|
118
|
+
| Tool | What it does |
|
|
119
|
+
|---|---|
|
|
120
|
+
| `human_screenshot` | Capture the page/element; returns the image to view, optionally saves it |
|
|
121
|
+
| `human_page_text` | Visible text of the whole page |
|
|
122
|
+
| `human_get_text` | Visible text of one element |
|
|
123
|
+
| `human_get_attribute` | An element's attribute (`aria-label`, `href`, …) |
|
|
124
|
+
| `human_get_html` | An element's `outerHTML` — discover the real selector of a control |
|
|
125
|
+
|
|
126
|
+
**Recording** — capture the session:
|
|
127
|
+
|
|
128
|
+
| Tool | What it does |
|
|
129
|
+
|---|---|
|
|
130
|
+
| `human_start_recording` | Begin capturing (frames + action timeline) |
|
|
131
|
+
| `human_stop_recording` | Finalize and write one or more files — `.mp4` / `.webm` / `.gif` / `.json` (e.g. video + timeline from one recording) |
|
|
132
|
+
|
|
133
|
+
**Sessions** — only needed for parallel browsers; the default session is implicit:
|
|
134
|
+
|
|
135
|
+
| Tool | What it does |
|
|
136
|
+
|---|---|
|
|
137
|
+
| `human_create_session` | Open a new isolated session (optional `personality`, `speed`, `width`/`height`) |
|
|
138
|
+
| `human_close_session` | Close a session |
|
|
139
|
+
| `human_list_sessions` | List open sessions |
|
|
140
|
+
|
|
141
|
+
**Config:**
|
|
142
|
+
|
|
143
|
+
| Tool | What it does |
|
|
144
|
+
|---|---|
|
|
145
|
+
| `human_set_personality` | Switch preset or blend two presets at runtime |
|
|
146
|
+
| `human_set_speed` | Switch humanization pace at runtime (`human` / `fast` / `instant`) |
|
|
147
|
+
| `human_set_viewport` | Resize the viewport at runtime (bigger/crisper recording, responsive testing) |
|
|
148
|
+
|
|
149
|
+
**Browser:**
|
|
150
|
+
|
|
151
|
+
| Tool | What it does |
|
|
152
|
+
|---|---|
|
|
153
|
+
| `human_browser_info` | Report the browser mode (ephemeral / persistent / CDP), channel, and whether logins persist |
|
|
154
|
+
| `human_enable_persistence` | Switch to a persistent profile so logins survive across runs (optionally restart now) |
|
|
155
|
+
| `human_restart_browser` | Restart the browser to apply a change, or recover a wedged one |
|
|
156
|
+
|
|
157
|
+
## Personalities
|
|
158
|
+
|
|
159
|
+
Four presets, each a different blend of speed, mouse curvature, typo rate, and reading pace:
|
|
160
|
+
|
|
161
|
+
- `careful` — deliberate, low error rate (default)
|
|
162
|
+
- `fast` — quick, minimal dwell
|
|
163
|
+
- `distracted` — overshoots, occasional typos and scroll corrections
|
|
164
|
+
- `precise` — straight paths, tight aim
|
|
165
|
+
|
|
166
|
+
Set the default with `HUMANJS_PERSONALITY`, override per session at creation, or change mid-session with `human_set_personality` ("now fill this form like a distracted user").
|
|
167
|
+
|
|
168
|
+
## Speed
|
|
169
|
+
|
|
170
|
+
How fast each action *executes* — orthogonal to personality:
|
|
171
|
+
|
|
172
|
+
- `human` (default) — full realistic pace. Best for polished demo recordings.
|
|
173
|
+
- `fast` — same humanized motion (Bezier paths, dwell, typing rhythm) at a brisk pace. A good fit when an agent is getting work done and you still want it to look human.
|
|
174
|
+
- `instant` — bypasses humanization entirely (straight Playwright, no visible motion). Maximum throughput when realism doesn't matter.
|
|
175
|
+
|
|
176
|
+
Set the default with `HUMANJS_SPEED`, override per session at creation (`human_create_session`), or change mid-session with `human_set_speed`.
|
|
177
|
+
|
|
178
|
+
> **Speed does not change the wait *between* actions.** That gap is the MCP client running one model inference per tool call — inherent to agentic tool use and outside this server's control. Speed only affects how long an action takes to run once it starts. To reduce between-action waiting, make fewer tool calls.
|
|
179
|
+
|
|
180
|
+
## Browser modes
|
|
181
|
+
|
|
182
|
+
By default each run gets a **fresh, empty browser** — predictable and isolated, but with no saved logins. Three ways to change that:
|
|
183
|
+
|
|
184
|
+
| You want… | Set | What you get |
|
|
185
|
+
|---|---|---|
|
|
186
|
+
| Stay logged in across runs | `HUMANJS_PERSIST=true` (or `HUMANJS_USER_DATA_DIR=/path`) | A dedicated HumanJS profile. Sign in once *in it*; it persists. Starts empty. |
|
|
187
|
+
| Drive a browser you launched | `HUMANJS_CDP_URL=http://localhost:9222` | Attach to a Chrome you started with `--remote-debugging-port` (see below). Reuses that instance's tabs and whatever you've signed into *there*. |
|
|
188
|
+
| A specific browser binary | `HUMANJS_CHANNEL=chrome` | Launches installed Chrome instead of bundled Chromium. **On its own, still a fresh profile** — combine with persistence or CDP for real logins. |
|
|
189
|
+
|
|
190
|
+
Common trap: `HUMANJS_CHANNEL=chrome` alone does **not** give you your existing Chrome cookies/logins — it only swaps the binary. To keep logins, use a persistent profile or CDP attach.
|
|
191
|
+
|
|
192
|
+
### Attaching over CDP
|
|
193
|
+
|
|
194
|
+
`HUMANJS_CDP_URL` connects to a browser **you launch yourself** with a remote-debugging port and a **separate profile dir**:
|
|
195
|
+
|
|
196
|
+
```bash
|
|
197
|
+
# macOS
|
|
198
|
+
"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" --remote-debugging-port=9222 --user-data-dir="$HOME/.humanjs-chrome"
|
|
199
|
+
|
|
200
|
+
# Linux
|
|
201
|
+
google-chrome --remote-debugging-port=9222 --user-data-dir="$HOME/.humanjs-chrome"
|
|
202
|
+
|
|
203
|
+
# Windows (PowerShell)
|
|
204
|
+
& "C:\Program Files\Google\Chrome\Application\chrome.exe" --remote-debugging-port=9222 --user-data-dir="$env:USERPROFILE\.humanjs-chrome"
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
Then set `HUMANJS_CDP_URL=http://localhost:9222`. Log into whatever you need in that window once; it lives in the `--user-data-dir` you chose (use a stable path like `~/.humanjs-chrome`, **not** `/tmp`, so it survives reboots).
|
|
208
|
+
|
|
209
|
+
> **You can't attach to your everyday Chrome.** Chrome only exposes a debug port when launched with the flag, and since ~v136 it **refuses `--remote-debugging-port` on your default profile** (a security fix that stopped malware reading your cookies via CDP). So a separate `--user-data-dir` is required — it's a distinct profile, not your normal one. If all you want is "stay logged in," `HUMANJS_PERSIST=true` is simpler and skips this dance entirely.
|
|
210
|
+
|
|
211
|
+
You can also toggle persistence from chat: `human_enable_persistence` (then `human_restart_browser` to apply now), and `human_browser_info` reports the current mode. Switching to a CDP browser stays env-only by design — it's a consent decision the agent shouldn't escalate into.
|
|
212
|
+
|
|
213
|
+
Persistent and CDP modes drive a **single shared browser**, so named/parallel sessions (`human_create_session`) aren't available in those modes — which is exactly what you want when the point is one logged-in browser.
|
|
214
|
+
|
|
215
|
+
> Library users (`@humanjs/playwright` directly) get all of this by creating the page themselves — see that package's "Using your own browser or a persistent profile" section.
|
|
216
|
+
|
|
217
|
+
## Recordings & dynamic UI
|
|
218
|
+
|
|
219
|
+
The server ships **built-in guidance** (sent to the agent on connect via MCP `instructions`), so you don't have to spell out the workflow each time. The agent is told to:
|
|
220
|
+
|
|
221
|
+
- **Explore first, then record one clean run — as a single batch.** Discover correct selectors in an un-recorded pass, then dispatch the whole run (`human_start_recording` → every action → `human_stop_recording`) in one turn. This is what makes recordings smooth: emitting the tool calls together means they fire back-to-back, whereas a step-by-step loop puts a multi-second model-inference pause between each action — dead air in the video. The motion is already humanized, so don't reach for `fast`/`instant` to "fix" the feel.
|
|
222
|
+
- **Use specific selectors on dynamic lists.** After a debounced search/filter the list reflows; the agent uses role/aria-label selectors (not text) so it targets the right element rather than a stale one.
|
|
223
|
+
|
|
224
|
+
**Exploration is on by default for recordings.** When you ask for a recording, the agent first runs an un-recorded pass to discover the right selectors, then records the clean batched run — you don't have to ask for it. A bare "record me buying a ticket on X" should produce a clean take without the play-by-play. To skip exploration (e.g. it's a simple flow, or you've already given the exact selectors), just tell the agent not to explore.
|
|
225
|
+
|
|
226
|
+
## Security
|
|
227
|
+
|
|
228
|
+
- **No arbitrary-JS `evaluate` tool.** Executing page-supplied JavaScript is a prompt-injection cliff — a malicious page could trick the agent into running code that exfiltrates data. The read-only inspection tools cover the legitimate "what's on the page" need.
|
|
229
|
+
- **File-path safety.** Tools that write files accept a basename only; path components (`../`, absolute paths) are rejected, so a prompt-injected filename can't escape `HUMANJS_OUTPUT_DIR`.
|
|
230
|
+
- **No credentials handling.** The server drives the browser; it doesn't manage logins, payment details, or secrets on your behalf.
|
|
231
|
+
- **Attaching to your real browser (CDP) is opt-in and env-only.** When you point `HUMANJS_CDP_URL` at your running browser, the agent acts with *your* live sessions — a bigger blast radius if a page tries to manipulate it. That's why it's a deliberate config choice you make up front, never something a tool can switch on.
|
|
232
|
+
|
|
233
|
+
## Honest limits
|
|
234
|
+
|
|
235
|
+
- Built on Playwright — humanizes it, doesn't replace it. Will not defeat sophisticated bot detection (fingerprinting, TLS, request patterns), and isn't meant to.
|
|
236
|
+
- One Chromium process backs the server; each session is an isolated context. Heavy parallel use is bounded by memory.
|
|
237
|
+
- Recording requires `ffmpeg` for video/gif output (bundled via the recorder); `.json` timelines have no such dependency.
|
|
238
|
+
|
|
239
|
+
## License
|
|
240
|
+
|
|
241
|
+
MIT
|