crawlforge-mcp-server 6.4.0 → 6.6.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.
Files changed (37) hide show
  1. package/CLAUDE.md +5 -5
  2. package/README.md +7 -6
  3. package/package.json +2 -1
  4. package/server.js +83 -15
  5. package/src/cli/commands/browser.js +77 -0
  6. package/src/cli/index.js +3 -1
  7. package/src/core/ActionExecutor.js +185 -7
  8. package/src/core/AuthManager.js +26 -0
  9. package/src/core/ChangeTracker.js +25 -8
  10. package/src/core/browser/SessionStore.js +331 -0
  11. package/src/core/browser/snapshot.js +346 -0
  12. package/src/core/llm/LLMManager.js +86 -6
  13. package/src/core/processing/PDFProcessor.js +3 -1
  14. package/src/server/fallbackHints.js +4 -0
  15. package/src/server/inlineThreshold.js +31 -1
  16. package/src/server/requestContext.js +26 -5
  17. package/src/server/toolFilter.js +2 -2
  18. package/src/server/transports/streamableHttp.js +38 -8
  19. package/src/skills/agent-skills/crawlforge-batch-automation/SKILL.md +9 -2
  20. package/src/skills/agent-skills/crawlforge-batch-automation/references/actions.md +50 -4
  21. package/src/skills/agent-skills/crawlforge-browser-sessions/SKILL.md +178 -0
  22. package/src/skills/agent-skills/crawlforge-getting-started/SKILL.md +7 -4
  23. package/src/skills/agent-skills/crawlforge-getting-started/references/cli.md +6 -1
  24. package/src/skills/agent-skills/crawlforge-getting-started/references/credits.md +4 -0
  25. package/src/skills/installer.js +1 -1
  26. package/src/tools/advanced/BrowserSessionTool.js +476 -0
  27. package/src/tools/advanced/ScrapeWithActionsTool.js +10 -1
  28. package/src/tools/crawl/mapSite.js +81 -7
  29. package/src/tools/extract/extractEmbeddedState.js +18 -2
  30. package/src/tools/extract/extractStructured.js +4 -0
  31. package/src/tools/extract/processDocument.js +94 -1
  32. package/src/tools/scrape/_brandingExtractor.js +23 -5
  33. package/src/tools/scrape/unifiedScrape.js +8 -1
  34. package/src/tools/search/redditSearch.js +24 -17
  35. package/src/utils/hiddenContent.js +67 -2
  36. package/src/utils/redditHosts.js +123 -0
  37. package/src/utils/robotsGate.js +27 -3
@@ -0,0 +1,178 @@
1
+ ---
2
+ name: crawlforge-browser-sessions
3
+ description: "Keeps one browser page alive across several tool calls with CrawlForge's browser_session tool. Use when the user needs to log in and then read pages behind that login, work through a multi-step flow (search, filter, paginate, fill a wizard), or look at a page before deciding what to click. The loop is: open a session on a URL, snapshot it to list the interactive elements with stable refs (@e1, @e2), act on those refs, read the content, close. Unlike scrape_with_actions, which is one-shot and closes its browser when the call returns, a session survives between calls, so one login is paid for once and a wrong selector costs one call instead of a whole chain."
4
+ metadata:
5
+ version: 5.6.6
6
+ source: crawlforge-mcp-server
7
+ ---
8
+
9
+ # CrawlForge Browser Sessions
10
+
11
+ Drive a real browser across several calls. `browser_session` keeps one page —
12
+ its cookies, its login, whatever it has already clicked — alive between calls, so
13
+ you can look at the page, act, and look again, instead of guessing a whole chain
14
+ of CSS selectors for a page you have never seen.
15
+
16
+ ## When to use
17
+
18
+ - **Log in once, then read several pages behind the login** → session.
19
+ - **You do not know what is on the page yet** — observe, then act → session.
20
+ - **A flow that spans more than one tool call** (wizard, filters, pagination,
21
+ multi-step form) → session.
22
+ - A **known, fixed** action chain on one page → `scrape_with_actions` instead:
23
+ one call, 5 credits, browser closed for you (see crawlforge-batch-automation).
24
+ - A page that renders **without interaction** → `scrape` (2 credits, see
25
+ crawlforge-web-scraping).
26
+
27
+ ## The loop
28
+
29
+ `open` → `snapshot` → `act` on the refs → (`snapshot` again after a navigation)
30
+ → `read` → `close`.
31
+
32
+ ```json
33
+ { "tool": "browser_session", "params": { "operation": "open", "url": "https://app.example.com/login" } }
34
+ ```
35
+
36
+ Returns a `sessionId` every later call passes as `session_id`, plus `expiresAt`
37
+ and `idleExpiresAt`.
38
+
39
+ ```json
40
+ { "tool": "browser_session", "params": { "operation": "snapshot", "session_id": "<id>" } }
41
+ ```
42
+
43
+ Returns an accessibility tree with a stable ref on every interactive element:
44
+
45
+ ```
46
+ [document] "Sign in"
47
+ @e1 [textbox] "Email"
48
+ @e2 [textbox] "Password"
49
+ @e3 [button] "Sign in"
50
+ ```
51
+
52
+ Act on those refs — a ref goes in `selector`, exactly where a CSS selector would:
53
+
54
+ ```json
55
+ {
56
+ "tool": "browser_session",
57
+ "params": {
58
+ "operation": "act",
59
+ "session_id": "<id>",
60
+ "actions": [
61
+ { "type": "type", "selector": "@e1", "text": "user@example.com" },
62
+ { "type": "type", "selector": "@e2", "text": "hunter2" },
63
+ { "type": "click", "selector": "@e3" },
64
+ { "type": "wait", "duration": 2000 }
65
+ ]
66
+ }
67
+ }
68
+ ```
69
+
70
+ `actions` is the same array `scrape_with_actions` takes: `wait`, `click`,
71
+ `type`, `press`, `scroll`, `select`, `hover`, `navigate`, `screenshot`,
72
+ `snapshot`, `executeJavaScript`. 1–20 per call; `continue_on_error: true` keeps
73
+ going past a failed one.
74
+
75
+ ```json
76
+ { "tool": "browser_session", "params": { "operation": "read", "session_id": "<id>", "formats": ["markdown"] } }
77
+ { "tool": "browser_session", "params": { "operation": "close", "session_id": "<id>" } }
78
+ ```
79
+
80
+ `read` extracts the **live** DOM — post-login, post-click — so it sees what a
81
+ fresh scrape of the same URL would not. `formats`: `markdown`, `html`, `text`,
82
+ `json`.
83
+
84
+ Other operations: `screenshot` (`full_page`, `format`, `quality`, `selector` —
85
+ a ref works there too; the image is stored as a
86
+ `crawlforge://screenshot/{actionId}` resource) and `list` (your open sessions).
87
+
88
+ ## Refs go stale on navigation
89
+
90
+ `@e1` is only valid for the page the snapshot was taken on. Any navigation —
91
+ clicking a link, submitting a form, an in-session `navigate` action — invalidates
92
+ every ref. A stale ref does not silently hit the wrong element; it fails and
93
+ tells you to take a new snapshot. **After anything that navigates, snapshot
94
+ again** before using refs.
95
+
96
+ `snapshot` is also available as an action type inside `scrape_with_actions`, for
97
+ the one-shot case where you want to observe and act within a single call.
98
+
99
+ ## Worked example — log in, then read the dashboard
100
+
101
+ ```json
102
+ {"tool":"browser_session","params":{"operation":"open","url":"https://app.example.com/login"}}
103
+ → { "sessionId": "8f2c…", "expiresAt": …, "idleExpiresAt": … }
104
+
105
+ {"tool":"browser_session","params":{"operation":"snapshot","session_id":"8f2c…"}}
106
+ → tree with @e1 [textbox] "Email", @e2 [textbox] "Password", @e3 [button] "Sign in"
107
+
108
+ {"tool":"browser_session","params":{"operation":"act","session_id":"8f2c…","actions":[
109
+ {"type":"type","selector":"@e1","text":"user@example.com"},
110
+ {"type":"type","selector":"@e2","text":"hunter2"},
111
+ {"type":"click","selector":"@e3"},
112
+ {"type":"wait","duration":2000}]}}
113
+ → success, url now https://app.example.com/dashboard
114
+
115
+ {"tool":"browser_session","params":{"operation":"snapshot","session_id":"8f2c…"}}
116
+ → fresh refs for the dashboard (the login refs are gone — the page navigated)
117
+
118
+ {"tool":"browser_session","params":{"operation":"read","session_id":"8f2c…","formats":["markdown"]}}
119
+ → the dashboard as markdown, logged in
120
+
121
+ {"tool":"browser_session","params":{"operation":"close","session_id":"8f2c…"}}
122
+ ```
123
+
124
+ Total: 3 + 1 + 1 + 1 + 2 + 1 = **9 credits**, and the login happened once. The
125
+ same flow as repeated `scrape_with_actions` calls costs 5 per call and logs in
126
+ again every time.
127
+
128
+ ## browser_session (cost: 3 to open, then 1–2 per call)
129
+
130
+ | Operation | Credits |
131
+ |-----------|---------|
132
+ | `open` | 3 |
133
+ | `read` | 2 |
134
+ | `snapshot` | 1 |
135
+ | `act` | 1 |
136
+ | `screenshot` | 1 |
137
+ | `close` | 1 |
138
+ | `list` | 1 |
139
+
140
+ The published flat rate is 3 — the ceiling, charged when an operation is not one
141
+ of the above. Nothing here is free.
142
+
143
+ ## Limits
144
+
145
+ - **Two clocks.** A session dies 600s after it opens (`ttl`, 30–3600) or 300s
146
+ after its last use (`activity_ttl`, 10–3600), whichever comes first. Close
147
+ sessions when you are done rather than leaving them to time out.
148
+ - **Concurrent sessions.** One account may hold **1** session at a time over
149
+ CrawlForge's hosted REST API; a local (stdio) or self-hosted install allows
150
+ **3** per API key, and the process itself caps the total. A session over the
151
+ cap is refused, never queued — `close` one first.
152
+ - **Sessions live in the server process** that opened them. They do not survive
153
+ a server restart, and they are not shared between installs.
154
+ - **`executeJavaScript` is refused** in a session on a remotely-served instance
155
+ (the script would run in a browser on the server, not on your machine). Use
156
+ `click` / `type` / `select` / `press`, or run the server locally over stdio.
157
+ - **Every in-session navigation is re-gated**: SSRF checks, the host blocklist
158
+ and robots.txt run again on each hop, not just at `open`.
159
+ - `stealth: true` on `open` runs the session in the anti-bot browser (see
160
+ crawlforge-stealth-browsing); `viewport` sets the window size.
161
+
162
+ ## CLI
163
+
164
+ ```bash
165
+ crawlforge browser https://example.com # open, snapshot, close — see the refs
166
+ crawlforge browser https://app.example.com --steps flow.json --read
167
+ ```
168
+
169
+ One invocation is one session: the CLI opens, snapshots, runs the steps in
170
+ `flow.json` (each `{"operation": …}` with the session supplied), optionally
171
+ reads, and closes. A session cannot span two CLI invocations — the page lives in
172
+ the process. Use the MCP tool when you need a session to outlive the call.
173
+
174
+ ## Cost note
175
+
176
+ An `open` + `snapshot` + `act` + `read` + `close` round trip is 8 credits, and
177
+ each extra look is 1. Reach for `scrape_with_actions` (5) when you can write the
178
+ whole interaction down in advance, and for a session when you cannot.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: crawlforge-getting-started
3
- description: "Orientation and tool-selection guide for the CrawlForge MCP server's 30 web tools. Use when the user is getting started with CrawlForge, asks which CrawlForge tool to use, how to set up the API key, how skills or the CLI work, what a tool costs in credits, or when one tool fails and a fallback is needed. Routes requests to the right specialized skill (web scraping, deep research, stealth, structured extraction, change tracking, batch automation), and explains MCP-tools-vs-CLI, the Ollama-first LLM fallback chain, and per-tool credit costs."
3
+ description: "Orientation and tool-selection guide for the CrawlForge MCP server's 31 web tools. Use when the user is getting started with CrawlForge, asks which CrawlForge tool to use, how to set up the API key, how skills or the CLI work, what a tool costs in credits, or when one tool fails and a fallback is needed. Routes requests to the right specialized skill (web scraping, deep research, stealth, structured extraction, change tracking, batch automation, browser sessions), and explains MCP-tools-vs-CLI, the Ollama-first LLM fallback chain, and per-tool credit costs."
4
4
  metadata:
5
5
  version: 5.6.6
6
6
  source: crawlforge-mcp-server
@@ -8,7 +8,7 @@ metadata:
8
8
 
9
9
  # CrawlForge: Getting Started
10
10
 
11
- CrawlForge is an MCP server with **30 tools** for web scraping, crawling,
11
+ CrawlForge is an MCP server with **31 tools** for web scraping, crawling,
12
12
  extraction, research, change tracking, and AI-compliance. This skill orients you
13
13
  and routes each request to the right specialized skill.
14
14
 
@@ -51,8 +51,9 @@ stored at `~/.crawlforge/config.json`.
51
51
  | Extract JSON/fields, parse a PDF, summarize, analyze sentiment | **crawlforge-structured-extraction** |
52
52
  | Watch a page for changes / monitor pricing | **crawlforge-change-tracking** |
53
53
  | Scrape many URLs, run browser actions, generate llms.txt | **crawlforge-batch-automation** |
54
+ | Keep a browser open across calls: log in then read, click through a multi-step flow | **crawlforge-browser-sessions** |
54
55
 
55
- ## The 30 tools at a glance
56
+ ## The 31 tools at a glance
56
57
 
57
58
  - **Basic (6):** fetch_url, extract_text, extract_links, extract_metadata, scrape_structured, read_result
58
59
  - **Unified (1):** scrape (multi-format single fetch)
@@ -62,12 +63,13 @@ stored at `~/.crawlforge/config.json`.
62
63
  - **Batch & automation (4):** batch_scrape, get_batch_results, scrape_with_actions, generate_llms_txt
63
64
  - **Stealth & locale (2):** stealth_mode, localization
64
65
  - **Templates & tracking (2):** scrape_template, track_changes
66
+ - **Browser sessions (1):** browser_session (one page kept alive across calls)
65
67
 
66
68
  ## MCP tools vs CLI
67
69
 
68
70
  - **MCP tools** — call inline within an AI assistant session (Claude Code,
69
71
  Cursor, etc.). This is the default in chat.
70
- - **CLI** (`crawlforge <command>`) — for scripts, CI, and pipelines. 15 tool
72
+ - **CLI** (`crawlforge <command>`) — for scripts, CI, and pipelines. 16 tool
71
73
  commands + 2 skill commands. See [cli](references/cli.md).
72
74
 
73
75
  Both hit the same backend and consume the same credits.
@@ -94,6 +96,7 @@ Do not suggest adding API keys — local Ollama is the intended zero-cost defaul
94
96
  | No template for a known site | `scrape_structured` → `extract_structured` → `extract_with_llm` |
95
97
  | LLM extraction unavailable (no Ollama/keys) | `scrape_structured` with CSS selectors |
96
98
  | Single page too slow / many pages | `batch_scrape` (async + webhook) |
99
+ | A `scrape_with_actions` chain keeps breaking on guessed selectors, or the flow needs more than one call | `browser_session` — snapshot for refs, then act (crawlforge-browser-sessions) |
97
100
  | Wrong region / currency shown | `localization` |
98
101
  | Need a big report but cost is high | lower `maxUrls` on `deep_research` |
99
102
  | Result came back `truncated: true` with a `result_handle` | `read_result` (search, slice, lines, json_path) — never fetch the page again |
@@ -22,7 +22,7 @@ crawlforge init # detect key, install skills, merge M
22
22
  | `--timeout <ms>` | Request timeout (default 30000). |
23
23
  | `--version` / `--help` | Version / help. |
24
24
 
25
- ## Tool commands (15)
25
+ ## Tool commands (16)
26
26
 
27
27
  | Command | Maps to | Example |
28
28
  |---------|---------|---------|
@@ -37,6 +37,7 @@ crawlforge init # detect key, install skills, merge M
37
37
  | `stealth <url>` | stealth_mode | `crawlforge stealth <url> --engine camoufox --screenshot` |
38
38
  | `batch <file>` | batch_scrape | `crawlforge batch urls.txt --format markdown --concurrency 10` |
39
39
  | `actions <url>` | scrape_with_actions | `crawlforge actions <url> --script flow.json --screenshot` |
40
+ | `browser <url>` | browser_session | `crawlforge browser <url> --steps flow.json --read` |
40
41
  | `localize <url>` | localization | `crawlforge localize <url> --locale fr-FR --country FR` |
41
42
  | `llmstxt <url>` | generate_llms_txt | `crawlforge llmstxt <url> --include-full` |
42
43
  | `template <id> <target>` | scrape_template | `crawlforge template github-repo https://github.com/owner/repo` |
@@ -68,4 +69,8 @@ crawlforge scrape https://example.com --quiet && echo ok # exit code only
68
69
  | `CRAWLFORGE_STEALTH_ENGINE` | Force `playwright` or `camoufox`. |
69
70
  | `CRAWLFORGE_BROWSER_BACKEND` | `local` or `browserbase`. |
70
71
 
72
+ `crawlforge browser` runs a whole session (open, snapshot, steps, close) in one
73
+ invocation — a session cannot span two CLI processes. Use the `browser_session`
74
+ MCP tool when a session has to outlive the call that opened it.
75
+
71
76
  Exit code 0 = success, 1 = error. `crawlforge <command> --help` for per-command help.
@@ -36,6 +36,7 @@ metered; there is no free tier. Tools marked "scales" cost more as work grows.
36
36
  | `analyze_content` | Sentiment / entities / keywords. |
37
37
  | `extract_structured` | Schema-driven (LLM + CSS fallback). |
38
38
  | `extract_with_llm` | NL-prompt extraction. |
39
+ | `browser_session` | Ceiling, charged for `open`. **Priced per operation:** `open` 3, `read` 2, `snapshot` / `act` / `screenshot` / `close` / `list` 1 each. |
39
40
 
40
41
  ## 4 credits
41
42
 
@@ -75,6 +76,9 @@ metered; there is no free tier. Tools marked "scales" cost more as work grows.
75
76
  - Cap dynamic tools: `deep_research`/`agent` via `maxUrls`, `crawl_deep` via
76
77
  `max_pages`, `batch_scrape` via the URL list size.
77
78
  - `get_batch_results` (1) is cheap — submit a batch once, page through results.
79
+ - A `browser_session` pays the 3-credit `open` once; every look after that is 1.
80
+ Use it when a flow spans several calls, and `scrape_with_actions` (5, one call)
81
+ when the whole interaction can be written down in advance.
78
82
  - A result over `max_inline_chars` costs nothing extra; read the stored copy with
79
83
  `read_result` (1) instead of fetching again.
80
84
  - On a site that blocks, one `scrape` with `escalate:true` costs at most 7 and
@@ -254,7 +254,7 @@ export async function uninstall({ target = 'all', cwd = process.cwd(), homeDir =
254
254
  const HOOK_MARKER = 'CrawlForge skill';
255
255
  const HOOK_COMMAND =
256
256
  "echo 'Consider whether a CrawlForge skill applies: web scraping, deep research, " +
257
- "stealth browsing, structured extraction, change tracking, or batch automation.'";
257
+ "stealth browsing, structured extraction, change tracking, batch automation, or browser sessions.'";
258
258
 
259
259
  /**
260
260
  * Add a UserPromptSubmit forced-eval reminder to ~/.claude/settings.json.