floorp-mcp 1.5.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 +270 -0
- package/dist/floorp-client.d.ts +133 -0
- package/dist/floorp-client.js +273 -0
- package/dist/floorp-client.js.map +1 -0
- package/dist/guards.d.ts +22 -0
- package/dist/guards.js +111 -0
- package/dist/guards.js.map +1 -0
- package/dist/html-find.d.ts +22 -0
- package/dist/html-find.js +95 -0
- package/dist/html-find.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +681 -0
- package/dist/index.js.map +1 -0
- package/dist/launch.d.ts +9 -0
- package/dist/launch.js +43 -0
- package/dist/launch.js.map +1 -0
- package/dist/os-input.d.ts +48 -0
- package/dist/os-input.js +339 -0
- package/dist/os-input.js.map +1 -0
- package/dist/probe.d.ts +5 -0
- package/dist/probe.js +31 -0
- package/dist/probe.js.map +1 -0
- package/package.json +54 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Arda Karaman
|
|
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,270 @@
|
|
|
1
|
+
# floorp-mcp
|
|
2
|
+
|
|
3
|
+
[](https://github.com/Frumane/floorp-mcp/actions/workflows/ci.yml)
|
|
4
|
+
[](LICENSE)
|
|
5
|
+
|
|
6
|
+
> An **MCP (Model Context Protocol)** server that lets AI assistants — Claude Code,
|
|
7
|
+
> Claude Desktop, Cursor, and any MCP client — **read pages, take screenshots and
|
|
8
|
+
> manage tabs** in the [Floorp](https://floorp.app) browser, using your real,
|
|
9
|
+
> logged-in browsing session.
|
|
10
|
+
|
|
11
|
+
Think "Claude in Chrome", but for Floorp (and other Firefox-based browsers on the
|
|
12
|
+
roadmap).
|
|
13
|
+
|
|
14
|
+
## How it works
|
|
15
|
+
|
|
16
|
+
Floorp ships a **built-in local automation server**. When you set
|
|
17
|
+
`floorp.mcp.enabled = true` in `about:config`, Floorp exposes an HTTP API on
|
|
18
|
+
`http://127.0.0.1:58261`. This project is a thin, well-documented MCP bridge that
|
|
19
|
+
translates MCP tool calls into requests against that API — **no browser extension
|
|
20
|
+
required**.
|
|
21
|
+
|
|
22
|
+
```
|
|
23
|
+
Claude Code / Desktop / Cursor
|
|
24
|
+
│ MCP (stdio)
|
|
25
|
+
▼
|
|
26
|
+
floorp-mcp ──HTTP──► Floorp :58261 ──► your real tabs
|
|
27
|
+
(this project) (built-in API)
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Requirements
|
|
31
|
+
|
|
32
|
+
- **Floorp** installed and running.
|
|
33
|
+
- In `about:config`, set **`floorp.mcp.enabled`** to `true`, then fully restart Floorp.
|
|
34
|
+
- **Node.js** ≥ 18.
|
|
35
|
+
|
|
36
|
+
## Setup
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
git clone https://github.com/Frumane/floorp-mcp
|
|
40
|
+
cd floorp-mcp
|
|
41
|
+
npm install
|
|
42
|
+
npm run build
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Register it with Claude Code (user-wide):
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
claude mcp add floorp -s user -- node /absolute/path/to/floorp-mcp/dist/index.js
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
…or add it to your MCP config manually:
|
|
52
|
+
|
|
53
|
+
```json
|
|
54
|
+
{
|
|
55
|
+
"mcpServers": {
|
|
56
|
+
"floorp": {
|
|
57
|
+
"command": "node",
|
|
58
|
+
"args": ["/absolute/path/to/floorp-mcp/dist/index.js"]
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Tools
|
|
65
|
+
|
|
66
|
+
**Tabs & reading**
|
|
67
|
+
|
|
68
|
+
| Tool | What it does |
|
|
69
|
+
|------|--------------|
|
|
70
|
+
| `list_tabs` | List all open tabs (title, URL, browserId, active, pinned). |
|
|
71
|
+
| `open_tab` | Open a new tab at a URL; **returns the new tab's `browserId`** so you can target it. |
|
|
72
|
+
| `get_active_tab` | Return the active tab's title, URL and browserId. |
|
|
73
|
+
| `navigate_tab` | Navigate an existing tab to a URL. |
|
|
74
|
+
| `close_tab` | Close a tab. |
|
|
75
|
+
| `read_page` | Read a tab's content as clean Markdown (or HTML / accessibility tree). Output is capped (default 25 KB) to protect the context. |
|
|
76
|
+
| `find` | **Fast element locator** — search a page server-side by visible text and/or tag; returns a compact list of ready-to-use CSS `selector`s (~1 KB) instead of the whole HTML. Use it to find a button/link/field, then act on the selector. |
|
|
77
|
+
| `snapshot` | Structured page map: Markdown with inline `fp:` refs + an element selector map — locate elements without grepping HTML, then act via a `ref`. |
|
|
78
|
+
| `screenshot` | Capture a screenshot of a tab (viewport or full page). |
|
|
79
|
+
| `launch_floorp` | Ensure Floorp is running — launches it if the API isn't reachable (Windows). |
|
|
80
|
+
|
|
81
|
+
**Interaction**
|
|
82
|
+
|
|
83
|
+
| Tool | What it does |
|
|
84
|
+
|------|--------------|
|
|
85
|
+
| `click` | Click an element by CSS selector **or a `ref` from `snapshot`**; auto-scrolls it into view first. |
|
|
86
|
+
| `type_text` | Type into an input/textarea — or a rich/contenteditable editor (Slate, ProseMirror…) — by CSS selector. |
|
|
87
|
+
| `fill_form` | Fill multiple fields at once. |
|
|
88
|
+
| `press_key` | Press a keyboard key (Enter, Tab, …). |
|
|
89
|
+
| `wait_for_element` | Wait for an element to attach / become visible / etc. |
|
|
90
|
+
| `get_value` | **Sensitive.** Read the current value of an input/textarea/select (can read password fields). |
|
|
91
|
+
|
|
92
|
+
Most tools target the **active tab** by default; pass a `browserId` (from
|
|
93
|
+
`list_tabs`) to target a specific tab.
|
|
94
|
+
|
|
95
|
+
**Real OS keyboard (Windows)** — for React/rich editors and bot-guarded submits
|
|
96
|
+
that ignore synthetic input:
|
|
97
|
+
|
|
98
|
+
| Tool | What it does |
|
|
99
|
+
|------|--------------|
|
|
100
|
+
| `real_type` | Type into the focused element via **genuine OS key events** (`isTrusted`). |
|
|
101
|
+
| `real_key` | Press a real key/combo, e.g. `"Enter"`, `"ctrl+a"`. |
|
|
102
|
+
| `real_clear` | Real Ctrl+A + Delete — reliably clears a rich/contenteditable field. |
|
|
103
|
+
|
|
104
|
+
These produce input a page can't distinguish from a human's, so they drive
|
|
105
|
+
React/Slate editors and submit composers that synthetic clicks/typing can't.
|
|
106
|
+
Workflow: `click` the field to focus it → `real_clear` / `real_type` / `real_key "Enter"`.
|
|
107
|
+
|
|
108
|
+
> **Safety guard:** OS keystrokes go to the foreground window, so before sending
|
|
109
|
+
> anything these tools bring Floorp to the foreground and **verify** it — if Floorp
|
|
110
|
+
> isn't running or can't be focused, they **abort without typing a single key**, so
|
|
111
|
+
> input can never leak into another app.
|
|
112
|
+
|
|
113
|
+
**Real OS mouse (Windows)** — genuine `isTrusted` clicks at screen coordinates:
|
|
114
|
+
|
|
115
|
+
| Tool | What it does |
|
|
116
|
+
|------|--------------|
|
|
117
|
+
| `window_bounds` | Floorp's window rectangle in screen pixels (to compute targets). |
|
|
118
|
+
| `move_cursor` | Move the real OS cursor to a screen pixel inside Floorp. |
|
|
119
|
+
| `real_click` | Real OS click (left/right, single/double) at a screen pixel inside Floorp. |
|
|
120
|
+
|
|
121
|
+
> **Double guard:** the click is sent only when Floorp is verified foreground **and**
|
|
122
|
+
> the point lies **inside Floorp's window rect** — a stray coordinate is refused, so
|
|
123
|
+
> a click can never land in another app/window. Coordinates are screen pixels
|
|
124
|
+
> (note display scaling/DPI when mapping from a screenshot).
|
|
125
|
+
|
|
126
|
+
**More interaction & queries**
|
|
127
|
+
|
|
128
|
+
| Tool | What it does |
|
|
129
|
+
|------|--------------|
|
|
130
|
+
| `hover` / `double_click` / `right_click` | Mouse gestures on an element (selector or `ref`). |
|
|
131
|
+
| `select_option` | Choose an option in a `<select>`. |
|
|
132
|
+
| `set_checked` | Check/uncheck a checkbox or radio. |
|
|
133
|
+
| `submit_form` | Submit a form. |
|
|
134
|
+
| `upload_file` | **Sensitive.** Set a file `<input>` by absolute path — restrict with `FLOORP_MCP_ALLOW_UPLOAD_DIRS`. |
|
|
135
|
+
| `get_attribute` | Read an element attribute (href, value, …). |
|
|
136
|
+
| `get_article` | Readability-extracted main article as Markdown. |
|
|
137
|
+
| `get_cookies` | **Sensitive.** Cookies visible to the page — values redacted unless `includeValues: true`. |
|
|
138
|
+
| `wait_for_network_idle` | Wait for network activity to settle. |
|
|
139
|
+
| `list_workspaces` / `switch_workspace` | Floorp workspaces (where supported). |
|
|
140
|
+
|
|
141
|
+
## Security
|
|
142
|
+
|
|
143
|
+
Understand the threat model before enabling this. Two risks dominate:
|
|
144
|
+
|
|
145
|
+
1. **Floorp's automation API has no authentication by default.** While
|
|
146
|
+
`floorp.mcp.enabled` is on, **any local process** can drive your logged-in
|
|
147
|
+
browser via `127.0.0.1:58261` — not just this server. There is also no
|
|
148
|
+
Origin check, so hostile web pages may attempt CSRF/DNS-rebinding tricks
|
|
149
|
+
against it. Mitigations:
|
|
150
|
+
- Turn `floorp.mcp.enabled` **off** when you're not using automation.
|
|
151
|
+
- Set the `FLOORP_MCP_TOKEN` environment variable — this server then sends it
|
|
152
|
+
as a `Bearer` token on every request (effective on Floorp builds that
|
|
153
|
+
enforce a token; harmless otherwise).
|
|
154
|
+
2. **Prompt injection ("lethal trifecta").** The assistant reads untrusted page
|
|
155
|
+
content *and* can act on your authenticated sessions (click, type, submit,
|
|
156
|
+
navigate, real OS input). A malicious page could try to instruct the
|
|
157
|
+
assistant to act against you. Treat everything read from a page as untrusted;
|
|
158
|
+
don't run automation unattended on sites you don't trust.
|
|
159
|
+
|
|
160
|
+
Hardening built into this server:
|
|
161
|
+
|
|
162
|
+
- **Real OS input is double-guarded:** keys/clicks are sent only after verifying
|
|
163
|
+
Floorp is the foreground window, and mouse clicks must land inside Floorp's
|
|
164
|
+
window rectangle — otherwise it aborts *without* sending anything. PowerShell
|
|
165
|
+
payloads are passed base64-encoded via process-private environment variables
|
|
166
|
+
(no shell interpolation, no temp script files on disk).
|
|
167
|
+
- **URL scheme + host allowlist:** `open_tab`/`navigate_tab` accept only `http(s)`
|
|
168
|
+
(and `about:blank`) by default, and **refuse loopback/private hosts**
|
|
169
|
+
(`127.0.0.1`, `localhost`, `10/8`, `172.16/12`, `192.168/16`, `169.254/16`,
|
|
170
|
+
IPv6 ULA/link-local). This stops a prompt-injected agent from pivoting the
|
|
171
|
+
browser onto Floorp's own API or your LAN and reading the response back. Lift
|
|
172
|
+
with `FLOORP_MCP_ALLOW_PRIVILEGED_URLS=1`. Optionally pin navigation to a
|
|
173
|
+
domain allowlist with `FLOORP_MCP_ALLOW_DOMAINS`.
|
|
174
|
+
- **Cookie values are redacted by default** in `get_cookies`; raw values require
|
|
175
|
+
an explicit `includeValues: true`.
|
|
176
|
+
- **`get_value` can read secrets:** browsers let same-origin JS read password
|
|
177
|
+
fields, so this tool *can* return a typed password. It's flagged SENSITIVE —
|
|
178
|
+
use it only on fields the user asked about, never to harvest credentials.
|
|
179
|
+
- **Upload allowlist:** set `FLOORP_MCP_ALLOW_UPLOAD_DIRS` (`;`-separated
|
|
180
|
+
directories) to confine `upload_file`. Paths are canonicalised with realpath
|
|
181
|
+
(symlinks resolved) and checked so `..`, a symlink, a same-prefix sibling
|
|
182
|
+
directory, or a UNC path can't escape the allowed folders.
|
|
183
|
+
- **`find` skips hidden elements** (inline `display:none`/`visibility:hidden`,
|
|
184
|
+
`hidden`, `type=hidden`, `aria-hidden`) so a page can't lure the agent into
|
|
185
|
+
clicking an invisible button via text search.
|
|
186
|
+
- **Input bounds:** numeric/text tool parameters are range- and length-capped
|
|
187
|
+
(coordinates, timeouts, `maxChars`, `find` limit, typed text, form fields) to
|
|
188
|
+
prevent resource-exhaustion / crash inputs.
|
|
189
|
+
- **Truncated API errors & validated port:** Floorp error bodies are truncated
|
|
190
|
+
before reaching the model; `FLOORP_MCP_PORT` is validated as 1–65535.
|
|
191
|
+
- **No `evaluate` tool:** arbitrary page-JS execution is deliberately not exposed.
|
|
192
|
+
|
|
193
|
+
What is **not** defended (inherent / Floorp-side): a malicious *local* process can
|
|
194
|
+
still read or impersonate the unauthenticated loopback API (plaintext, no TLS), and
|
|
195
|
+
prompt injection from a page you choose to automate can still drive legitimate
|
|
196
|
+
actions on that page. Disable `floorp.mcp.enabled` when idle and don't automate
|
|
197
|
+
untrusted sites unattended.
|
|
198
|
+
|
|
199
|
+
| Environment variable | Effect |
|
|
200
|
+
|---|---|
|
|
201
|
+
| `FLOORP_MCP_TOKEN` | Sent as `Authorization: Bearer …` to the Floorp API. |
|
|
202
|
+
| `FLOORP_MCP_PORT` | API port (default `58261`, validated 1–65535). |
|
|
203
|
+
| `FLOORP_MCP_ALLOW_PRIVILEGED_URLS` | `1` allows non-http(s) URLs **and** loopback/private hosts in open/navigate. |
|
|
204
|
+
| `FLOORP_MCP_ALLOW_DOMAINS` | Comma-separated domain allowlist for navigation (subdomains included). Unset = any public host. |
|
|
205
|
+
| `FLOORP_MCP_ALLOW_UPLOAD_DIRS` | Restrict `upload_file` to these directories (`;`-separated). |
|
|
206
|
+
| `FLOORP_PATH` | Full path to `floorp.exe` for `launch_floorp`. |
|
|
207
|
+
|
|
208
|
+
## Performance
|
|
209
|
+
|
|
210
|
+
- **HTTP tool calls are cheap** — a full attach → act → detach round-trip against
|
|
211
|
+
Floorp's local API is ~5–6 ms. `find` searches the page server-side and returns
|
|
212
|
+
~1 KB of ready-to-use selectors instead of dumping the whole HTML, and
|
|
213
|
+
`read_page` is capped (default 25 KB) so a page read can't flood the context.
|
|
214
|
+
- **Real OS input uses a persistent PowerShell host.** Spawning `powershell.exe`
|
|
215
|
+
(~700 ms) and compiling the P/Invoke helper (~600 ms) used to happen on *every*
|
|
216
|
+
`real_*`/`move_cursor`/`window_bounds` call (~1.9 s each). Now one host is
|
|
217
|
+
started lazily, compiles once, and runs a read-eval loop — so the first call
|
|
218
|
+
pays ~1.6 s but every call after is **~350 ms** for a guarded key/click (~5×
|
|
219
|
+
faster) and a few ms for a window-bounds query. The foreground/bounds safety
|
|
220
|
+
guards still run on every command; the host is recycled if it hangs or dies.
|
|
221
|
+
|
|
222
|
+
## Notes & limitations
|
|
223
|
+
|
|
224
|
+
Learned from driving real apps (incl. Google Flow):
|
|
225
|
+
|
|
226
|
+
- **Rich editors:** `type_text` handles plain inputs *and* contenteditable editors
|
|
227
|
+
(Slate, ProseMirror, Lexical) — it falls back to dispatching a real text-input
|
|
228
|
+
event when an element has no `.value`. Reliably *clearing* such editors isn't
|
|
229
|
+
solved yet (no `select-all`/`evaluate`).
|
|
230
|
+
- **Submitting React composers:** many chat/prompt composers submit on a real
|
|
231
|
+
**Enter keydown**, not on a synthetic click of the send button. Prefer
|
|
232
|
+
`press_key` `"Enter"` over `click` for those.
|
|
233
|
+
- **Trusted events:** you cannot forge `isTrusted=true` from page JavaScript — it
|
|
234
|
+
is a browser security invariant. Floorp injects input at a privileged layer, so
|
|
235
|
+
ordinary clicks/keys behave like real ones; but flows guarded by reCAPTCHA or
|
|
236
|
+
strict bot-detection may still refuse automated submission.
|
|
237
|
+
- **`evaluate`:** the page-JS eval endpoint returns HTTP 404 on some Floorp builds,
|
|
238
|
+
so it is not exposed as a tool here.
|
|
239
|
+
- **Multiple windows:** when more than one window is open, the "active tab" is
|
|
240
|
+
ambiguous (each window has its own active tab). Prefer the `browserId` returned
|
|
241
|
+
by `open_tab`, or one from `list_tabs`, and pass it explicitly to every tool.
|
|
242
|
+
|
|
243
|
+
## Roadmap
|
|
244
|
+
|
|
245
|
+
- [x] Tab management, page reading, screenshots
|
|
246
|
+
- [x] Interaction tools: click, type, fill forms, key presses, read field values
|
|
247
|
+
- [x] Real OS keyboard (Windows): `real_type` / `real_key` / `real_clear`, with a
|
|
248
|
+
foreground safety guard — drives React/Slate editors & bot-guarded submits
|
|
249
|
+
- [x] `snapshot` (fingerprint refs + selector map) + `click` by `ref` + auto-scroll-into-view
|
|
250
|
+
- [x] `launch_floorp` — start Floorp if not running (Windows)
|
|
251
|
+
- [x] Extra tools: hover, double/right-click, select_option, set_checked, submit,
|
|
252
|
+
upload_file, get_attribute, get_article, get_cookies, wait_for_network_idle, workspaces
|
|
253
|
+
- [x] Real OS mouse (Windows): `window_bounds` / `move_cursor` / `real_click`, with a
|
|
254
|
+
foreground + in-window-bounds double guard
|
|
255
|
+
- [ ] WebDriver BiDi engine — non-Floorp Firefox forks + JS `evaluate` + element-relative native input
|
|
256
|
+
- [ ] macOS / Linux native-input backends
|
|
257
|
+
- [ ] JS `evaluate` (available in newer Floorp builds; older ones return HTTP 404)
|
|
258
|
+
- [ ] Optional bearer-token auth
|
|
259
|
+
- [ ] Support for other Firefox-based browsers (WebDriver BiDi fallback)
|
|
260
|
+
|
|
261
|
+
## Acknowledgements
|
|
262
|
+
|
|
263
|
+
Built against the automation API exposed by Floorp. The official
|
|
264
|
+
[`Floorp-Projects/floorp-mcp-server`](https://github.com/Floorp-Projects/floorp-mcp-server)
|
|
265
|
+
was a useful reference for mapping the endpoint surface. This is an independent,
|
|
266
|
+
clean-room MIT-licensed implementation.
|
|
267
|
+
|
|
268
|
+
## License
|
|
269
|
+
|
|
270
|
+
[MIT](./LICENSE) © Arda Karaman
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Thin HTTP client for Floorp's built-in automation API.
|
|
3
|
+
*
|
|
4
|
+
* Floorp exposes this API on http://127.0.0.1:58261 once `floorp.mcp.enabled`
|
|
5
|
+
* is set to `true` in about:config. The model is instance-based: to operate on
|
|
6
|
+
* a tab you first obtain an `instanceId` (by attaching to an existing tab or by
|
|
7
|
+
* creating a new one), then issue per-instance commands.
|
|
8
|
+
*
|
|
9
|
+
* Lifecycle (verified against a live Floorp):
|
|
10
|
+
* - attach(browserId) -> ephemeral handle to an EXISTING tab
|
|
11
|
+
* - createTab(url) -> opens a NEW tab, returns a handle
|
|
12
|
+
* - detach(instanceId) [DELETE] -> releases the handle, tab stays open
|
|
13
|
+
* - closeTab(instanceId) [close] -> actually closes the tab
|
|
14
|
+
*/
|
|
15
|
+
export interface TabInfo {
|
|
16
|
+
browserId: string;
|
|
17
|
+
windowId: string;
|
|
18
|
+
title: string;
|
|
19
|
+
url: string;
|
|
20
|
+
selected: boolean;
|
|
21
|
+
pinned: boolean;
|
|
22
|
+
}
|
|
23
|
+
export interface CreateTabOptions {
|
|
24
|
+
background?: boolean;
|
|
25
|
+
waitForLoad?: boolean;
|
|
26
|
+
}
|
|
27
|
+
export type TextMode = "full" | "scoped" | "visible";
|
|
28
|
+
export type ElementState = "attached" | "visible" | "hidden" | "detached";
|
|
29
|
+
export interface EvaluateResult {
|
|
30
|
+
success: boolean;
|
|
31
|
+
result?: unknown;
|
|
32
|
+
resultType?: string;
|
|
33
|
+
error?: string;
|
|
34
|
+
errorType?: string;
|
|
35
|
+
}
|
|
36
|
+
export declare class FloorpClient {
|
|
37
|
+
private readonly baseUrl;
|
|
38
|
+
private readonly token;
|
|
39
|
+
constructor(port?: number, token?: string);
|
|
40
|
+
private request;
|
|
41
|
+
private static stripImagePrefix;
|
|
42
|
+
health(): Promise<boolean>;
|
|
43
|
+
listTabs(): Promise<TabInfo[]>;
|
|
44
|
+
/** The currently selected tab. Throws if none is reported. */
|
|
45
|
+
activeTab(): Promise<TabInfo>;
|
|
46
|
+
/** Open a NEW tab and return its instance handle. */
|
|
47
|
+
createTab(url: string, opts?: CreateTabOptions): Promise<string>;
|
|
48
|
+
/** Resolve the live browserId behind an instance handle. */
|
|
49
|
+
getInstanceBrowserId(instanceId: string): Promise<string | null>;
|
|
50
|
+
/** Attach an ephemeral handle to an EXISTING tab. */
|
|
51
|
+
attach(browserId: string): Promise<string | null>;
|
|
52
|
+
/** Release a handle WITHOUT closing the tab. */
|
|
53
|
+
detach(instanceId: string): Promise<void>;
|
|
54
|
+
/** Actually close the tab behind a handle. */
|
|
55
|
+
closeTab(instanceId: string): Promise<void>;
|
|
56
|
+
navigate(instanceId: string, url: string): Promise<void>;
|
|
57
|
+
getUri(instanceId: string): Promise<string | null>;
|
|
58
|
+
getTitle(instanceId: string): Promise<string | null>;
|
|
59
|
+
/** Page content as clean Markdown. */
|
|
60
|
+
getText(instanceId: string, mode?: TextMode): Promise<string>;
|
|
61
|
+
getHtml(instanceId: string, selector?: string): Promise<string>;
|
|
62
|
+
getAccessibilityTree(instanceId: string): Promise<unknown>;
|
|
63
|
+
/** Viewport screenshot as base64 PNG (no data-URL prefix). */
|
|
64
|
+
screenshot(instanceId: string): Promise<string | null>;
|
|
65
|
+
/** Full-page screenshot as base64 PNG (no data-URL prefix). */
|
|
66
|
+
fullPageScreenshot(instanceId: string): Promise<string | null>;
|
|
67
|
+
/** POST a per-instance action; treat an explicit `{ ok: false }` as failure. */
|
|
68
|
+
private action;
|
|
69
|
+
/** Scroll an element (by selector or fingerprint) into view. */
|
|
70
|
+
scrollTo(instanceId: string, selector?: string, fingerprint?: string): Promise<void>;
|
|
71
|
+
click(instanceId: string, selector?: string, opts?: {
|
|
72
|
+
button?: "left" | "right" | "middle";
|
|
73
|
+
clickCount?: number;
|
|
74
|
+
force?: boolean;
|
|
75
|
+
fingerprint?: string;
|
|
76
|
+
}): Promise<void>;
|
|
77
|
+
/**
|
|
78
|
+
* Structured page snapshot: clean Markdown text with inline fingerprint refs
|
|
79
|
+
* (`<!--fp:...-->`) plus an "Element Selector Map" (fp | tag | text). Lets an
|
|
80
|
+
* agent locate elements without grepping raw HTML, then act via a `ref`.
|
|
81
|
+
*/
|
|
82
|
+
snapshot(instanceId: string, mode?: TextMode): Promise<string>;
|
|
83
|
+
/** Set the value of an input/textarea. */
|
|
84
|
+
input(instanceId: string, selector: string, value: string, opts?: {
|
|
85
|
+
typingMode?: boolean;
|
|
86
|
+
typingDelayMs?: number;
|
|
87
|
+
}): Promise<void>;
|
|
88
|
+
clearInput(instanceId: string, selector: string): Promise<void>;
|
|
89
|
+
/** Fill several fields at once: keys are CSS selectors, values are strings. */
|
|
90
|
+
fillForm(instanceId: string, formData: Record<string, string>): Promise<void>;
|
|
91
|
+
pressKey(instanceId: string, key: string): Promise<void>;
|
|
92
|
+
/**
|
|
93
|
+
* Insert text into a rich / contenteditable editor (Slate, ProseMirror, Lexical…)
|
|
94
|
+
* by dispatching a real text-input event. Use this when `input` fails because the
|
|
95
|
+
* element has no `.value` (i.e. it is not a plain <input>/<textarea>).
|
|
96
|
+
*/
|
|
97
|
+
dispatchTextInput(instanceId: string, selector: string, text: string): Promise<void>;
|
|
98
|
+
/** Read the current value of an input/textarea/select. */
|
|
99
|
+
getValue(instanceId: string, selector: string): Promise<string | null>;
|
|
100
|
+
waitForElement(instanceId: string, selector: string, state?: ElementState, timeout?: number): Promise<boolean>;
|
|
101
|
+
/**
|
|
102
|
+
* Evaluate JavaScript in the page context (supports async/await).
|
|
103
|
+
* NOTE: not exposed in all Floorp builds — older ones return HTTP 404.
|
|
104
|
+
*/
|
|
105
|
+
evaluate(instanceId: string, script: string): Promise<EvaluateResult>;
|
|
106
|
+
hover(instanceId: string, selector?: string, fingerprint?: string): Promise<void>;
|
|
107
|
+
doubleClick(instanceId: string, selector?: string, fingerprint?: string): Promise<void>;
|
|
108
|
+
rightClick(instanceId: string, selector?: string, fingerprint?: string): Promise<void>;
|
|
109
|
+
/** Choose an option in a <select> by value. */
|
|
110
|
+
selectOption(instanceId: string, selector: string, value: string): Promise<void>;
|
|
111
|
+
/** Check/uncheck a checkbox or radio. */
|
|
112
|
+
setChecked(instanceId: string, selector: string, checked: boolean): Promise<void>;
|
|
113
|
+
/** Submit a form (by a selector inside/of the form). */
|
|
114
|
+
submitForm(instanceId: string, selector?: string): Promise<void>;
|
|
115
|
+
/** Set a file input's file by absolute path. */
|
|
116
|
+
uploadFile(instanceId: string, selector: string, filePath: string): Promise<void>;
|
|
117
|
+
getAttribute(instanceId: string, name: string, selector?: string, fingerprint?: string): Promise<string | null>;
|
|
118
|
+
/** Readability-extracted main article (title, byline, markdown). */
|
|
119
|
+
getArticle(instanceId: string): Promise<{
|
|
120
|
+
title?: string;
|
|
121
|
+
byline?: string;
|
|
122
|
+
markdown?: string;
|
|
123
|
+
length?: number;
|
|
124
|
+
} | null>;
|
|
125
|
+
getCookies(instanceId: string): Promise<unknown[]>;
|
|
126
|
+
/** Wait until network activity settles (good after navigation/SPA loads). */
|
|
127
|
+
waitForNetworkIdle(instanceId: string, timeout?: number): Promise<boolean>;
|
|
128
|
+
listWorkspaces(): Promise<Array<{
|
|
129
|
+
id: string;
|
|
130
|
+
name: string;
|
|
131
|
+
}>>;
|
|
132
|
+
switchWorkspace(id: string): Promise<boolean>;
|
|
133
|
+
}
|