firecrawl-mcp 3.21.4 → 3.22.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/README.md +20 -2
- package/dist/index.js +64 -13
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -26,6 +26,24 @@ A Model Context Protocol (MCP) server that brings [Firecrawl](https://github.com
|
|
|
26
26
|
|
|
27
27
|
## Installation
|
|
28
28
|
|
|
29
|
+
### Hosted MCP (keyless free tier)
|
|
30
|
+
|
|
31
|
+
Connect to the remote hosted server with no setup:
|
|
32
|
+
|
|
33
|
+
```
|
|
34
|
+
https://mcp.firecrawl.dev/v2/mcp
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
On the keyless free tier, `scrape`, `search`, and `interact` work without an API key (rate-limited). Other tools such as `crawl`, `map`, `agent`, and `extract` still need a key.
|
|
38
|
+
|
|
39
|
+
Prefer an API key or OAuth whenever the human can sign up. It unlocks the full tool set and higher limits. With a key, use:
|
|
40
|
+
|
|
41
|
+
```
|
|
42
|
+
https://mcp.firecrawl.dev/{FIRECRAWL_API_KEY}/v2/mcp
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
See the [MCP server docs](https://docs.firecrawl.dev/mcp-server) and the [agent onboarding guide](https://www.firecrawl.dev/agent-onboarding/SKILL.md) for setup details.
|
|
46
|
+
|
|
29
47
|
### Running with npx
|
|
30
48
|
|
|
31
49
|
```bash
|
|
@@ -326,14 +344,14 @@ Use this guide to select the right tool for your task:
|
|
|
326
344
|
- **If you want to search the web for info:** use **search**
|
|
327
345
|
- **If you need complex research across multiple unknown sources:** use **agent**
|
|
328
346
|
- **If you want to analyze a whole site or section:** use **crawl** (with limits!)
|
|
329
|
-
- **If you need interactive browser automation** (click, type, navigate): use **scrape** + **interact**
|
|
347
|
+
- **If you need interactive browser automation** (click, type, navigate): use **interact** with a URL for a fresh page, or **scrape** + **interact** when you already scraped the page or need tighter scrape control
|
|
330
348
|
|
|
331
349
|
### Quick Reference Table
|
|
332
350
|
|
|
333
351
|
| Tool | Best for | Returns |
|
|
334
352
|
| ------------ | ---------------------------------------------- | ------------------------------ |
|
|
335
353
|
| scrape | Single page content | JSON (preferred) or markdown |
|
|
336
|
-
| interact | Interact with a scraped page
|
|
354
|
+
| interact | Interact with a URL or scraped page | Execution result + scrapeId for URL mode |
|
|
337
355
|
| batch_scrape | Multiple known URLs | JSON (preferred) or markdown[] |
|
|
338
356
|
| map | Discovering URLs on a site | URL[] |
|
|
339
357
|
| crawl | Multi-page extraction (with limits) | markdown/html[] |
|
package/dist/index.js
CHANGED
|
@@ -3846,24 +3846,28 @@ server.addTool({
|
|
|
3846
3846
|
// Transient page interactions only; does not delete monitors, jobs, or external sites.
|
|
3847
3847
|
},
|
|
3848
3848
|
description: `
|
|
3849
|
-
Interact with a
|
|
3849
|
+
Interact with a page in a live browser session: click buttons, fill forms, extract dynamic content, or navigate deeper.
|
|
3850
3850
|
|
|
3851
3851
|
**Best for:** Multi-step workflows on a single page \u2014 searching a site, clicking through results, filling forms, extracting data that requires interaction.
|
|
3852
|
-
**
|
|
3852
|
+
**Two ways to target a page:**
|
|
3853
|
+
- Pass a \`url\` to interact directly. The session is opened for you in one call (use this for a fresh page).
|
|
3854
|
+
- Pass a \`scrapeId\` from a previous firecrawl_scrape to reuse that already-loaded page (cheaper when you just scraped it).
|
|
3853
3855
|
|
|
3854
3856
|
**Arguments:**
|
|
3855
|
-
-
|
|
3857
|
+
- url: Page to interact with; opens a session for you (use this OR scrapeId)
|
|
3858
|
+
- scrapeId: Scrape job ID from a previous scrape, found in its metadata (use this OR url)
|
|
3856
3859
|
- prompt: Natural language instruction describing the action to take (use this OR code)
|
|
3857
3860
|
- code: Code to execute in the browser session (use this OR prompt)
|
|
3858
3861
|
- language: "bash", "python", or "node" (optional, defaults to "node", only used with code)
|
|
3859
|
-
- timeout:
|
|
3862
|
+
- timeout: Interact execution timeout in seconds, 1-300 (optional, defaults to 30)
|
|
3863
|
+
- scrapeOptions: Optional scrape controls used only with url mode, such as waitFor, maxAge, proxy, or zeroDataRetention
|
|
3860
3864
|
|
|
3861
|
-
**Usage Example (prompt):**
|
|
3865
|
+
**Usage Example (prompt, direct via url):**
|
|
3862
3866
|
\`\`\`json
|
|
3863
3867
|
{
|
|
3864
3868
|
"name": "firecrawl_interact",
|
|
3865
3869
|
"arguments": {
|
|
3866
|
-
"
|
|
3870
|
+
"url": "https://example.com/products",
|
|
3867
3871
|
"prompt": "Click on the first product and tell me its price"
|
|
3868
3872
|
}
|
|
3869
3873
|
}
|
|
@@ -3883,24 +3887,71 @@ Interact with a previously scraped page in a live browser session. Scrape a page
|
|
|
3883
3887
|
**Returns:** Execution result including output, stdout, stderr, exit code, and live view URLs.
|
|
3884
3888
|
`,
|
|
3885
3889
|
parameters: z4.object({
|
|
3886
|
-
scrapeId: z4.string(),
|
|
3887
|
-
|
|
3888
|
-
|
|
3890
|
+
scrapeId: z4.string().trim().min(1).optional(),
|
|
3891
|
+
url: z4.string().trim().url().optional(),
|
|
3892
|
+
prompt: z4.string().trim().min(1).optional(),
|
|
3893
|
+
code: z4.string().trim().min(1).optional(),
|
|
3889
3894
|
language: z4.enum(["bash", "python", "node"]).optional(),
|
|
3890
|
-
timeout: z4.number().min(1).max(300).optional()
|
|
3895
|
+
timeout: z4.number().min(1).max(300).optional(),
|
|
3896
|
+
scrapeOptions: scrapeParamsSchema.omit({ url: true }).partial().optional()
|
|
3897
|
+
}).refine((data) => Boolean(data.scrapeId) !== Boolean(data.url), {
|
|
3898
|
+
message: "Provide either 'url' (interact directly) or 'scrapeId' (reuse a previous scrape), not both."
|
|
3899
|
+
}).refine((data) => !data.scrapeOptions || Boolean(data.url), {
|
|
3900
|
+
message: "scrapeOptions can only be used with 'url' mode."
|
|
3891
3901
|
}).refine((data) => data.code || data.prompt, {
|
|
3892
3902
|
message: "Either 'code' or 'prompt' must be provided."
|
|
3893
3903
|
}),
|
|
3894
3904
|
execute: async (args2, { session, log }) => {
|
|
3895
3905
|
const client = getClient(session);
|
|
3896
|
-
const {
|
|
3897
|
-
|
|
3906
|
+
const {
|
|
3907
|
+
scrapeId: providedScrapeId,
|
|
3908
|
+
url,
|
|
3909
|
+
prompt,
|
|
3910
|
+
code,
|
|
3911
|
+
language,
|
|
3912
|
+
timeout,
|
|
3913
|
+
scrapeOptions
|
|
3914
|
+
} = args2;
|
|
3915
|
+
let scrapeId = providedScrapeId;
|
|
3916
|
+
const openedFromUrl = !scrapeId;
|
|
3917
|
+
if (openedFromUrl) {
|
|
3918
|
+
log.info("Opening interact session from url", { url });
|
|
3919
|
+
const cleanedScrapeOptions = removeEmptyTopLevel(scrapeOptions ?? {});
|
|
3920
|
+
const scraped = await client.scrape(String(url), {
|
|
3921
|
+
...cleanedScrapeOptions,
|
|
3922
|
+
origin: ORIGIN
|
|
3923
|
+
});
|
|
3924
|
+
scrapeId = scraped?.metadata?.scrapeId;
|
|
3925
|
+
if (!scrapeId) {
|
|
3926
|
+
return asText2({
|
|
3927
|
+
error: "Could not open an interact session: the scrape did not return a scrapeId. Try firecrawl_scrape first, then pass its scrapeId.",
|
|
3928
|
+
url
|
|
3929
|
+
});
|
|
3930
|
+
}
|
|
3931
|
+
}
|
|
3932
|
+
if (!scrapeId) {
|
|
3933
|
+
return asText2({
|
|
3934
|
+
error: "Could not open an interact session: missing scrapeId.",
|
|
3935
|
+
url
|
|
3936
|
+
});
|
|
3937
|
+
}
|
|
3938
|
+
const activeScrapeId = scrapeId;
|
|
3939
|
+
log.info("Interacting with page", { scrapeId: activeScrapeId });
|
|
3898
3940
|
const interactArgs = { origin: ORIGIN };
|
|
3899
3941
|
if (prompt) interactArgs.prompt = prompt;
|
|
3900
3942
|
if (code) interactArgs.code = code;
|
|
3901
3943
|
if (language) interactArgs.language = language;
|
|
3902
3944
|
if (timeout != null) interactArgs.timeout = timeout;
|
|
3903
|
-
const res = await client.interact(
|
|
3945
|
+
const res = await client.interact(activeScrapeId, interactArgs);
|
|
3946
|
+
if (openedFromUrl && res && typeof res === "object" && !Array.isArray(res)) {
|
|
3947
|
+
return asText2({
|
|
3948
|
+
...res,
|
|
3949
|
+
scrapeId: activeScrapeId
|
|
3950
|
+
});
|
|
3951
|
+
}
|
|
3952
|
+
if (openedFromUrl) {
|
|
3953
|
+
return asText2({ scrapeId: activeScrapeId, result: res });
|
|
3954
|
+
}
|
|
3904
3955
|
return asText2(res);
|
|
3905
3956
|
}
|
|
3906
3957
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "firecrawl-mcp",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.22.0",
|
|
4
4
|
"description": "MCP server for Firecrawl — search, scrape, and interact with the web. Supports both cloud and self-hosted instances. Features include web search, scraping, page interaction, batch processing, and LLM-powered content analysis.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"mcpName": "io.github.firecrawl/firecrawl-mcp-server",
|