firecrawl-mcp 3.9.0 → 3.10.2
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 +7 -2
- package/dist/index.js +122 -50
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -818,19 +818,23 @@ Check the status of an agent job and retrieve results when complete. Use this to
|
|
|
818
818
|
|
|
819
819
|
### 11. Browser Create (`firecrawl_browser_create`)
|
|
820
820
|
|
|
821
|
-
Create a
|
|
821
|
+
Create a cloud browser session for interactive automation.
|
|
822
822
|
|
|
823
823
|
**Best for:**
|
|
824
824
|
|
|
825
825
|
- Multi-step browser automation (navigate, click, fill forms, extract data)
|
|
826
826
|
- Interactive workflows that require maintaining state across actions
|
|
827
827
|
- Testing and debugging web pages in a live browser
|
|
828
|
+
- Saving and reusing browser state with profiles
|
|
828
829
|
|
|
829
830
|
**Arguments:**
|
|
830
831
|
|
|
831
832
|
- `ttl`: Total session lifetime in seconds (30-3600, optional)
|
|
832
833
|
- `activityTtl`: Idle timeout in seconds (10-3600, optional)
|
|
833
834
|
- `streamWebView`: Whether to enable live view streaming (optional)
|
|
835
|
+
- `profile`: Save and reuse browser state across sessions (optional)
|
|
836
|
+
- `name`: Profile name (sessions with the same name share state)
|
|
837
|
+
- `saveChanges`: Whether to save changes back to the profile (default: true)
|
|
834
838
|
|
|
835
839
|
**Usage Example:**
|
|
836
840
|
|
|
@@ -838,7 +842,8 @@ Create a persistent cloud browser session for interactive automation.
|
|
|
838
842
|
{
|
|
839
843
|
"name": "firecrawl_browser_create",
|
|
840
844
|
"arguments": {
|
|
841
|
-
"ttl": 600
|
|
845
|
+
"ttl": 600,
|
|
846
|
+
"profile": { "name": "my-profile", "saveChanges": true }
|
|
842
847
|
}
|
|
843
848
|
}
|
|
844
849
|
```
|
package/dist/index.js
CHANGED
|
@@ -142,43 +142,100 @@ const otherActions = [
|
|
|
142
142
|
const allActionTypes = [...safeActionTypes, ...otherActions];
|
|
143
143
|
// Use appropriate action types based on safe mode
|
|
144
144
|
const allowedActionTypes = SAFE_MODE ? safeActionTypes : allActionTypes;
|
|
145
|
+
function buildFormatsArray(args) {
|
|
146
|
+
const formats = args.formats;
|
|
147
|
+
if (!formats || formats.length === 0)
|
|
148
|
+
return undefined;
|
|
149
|
+
const result = [];
|
|
150
|
+
for (const fmt of formats) {
|
|
151
|
+
if (fmt === 'json') {
|
|
152
|
+
const jsonOpts = args.jsonOptions;
|
|
153
|
+
result.push({ type: 'json', ...jsonOpts });
|
|
154
|
+
}
|
|
155
|
+
else if (fmt === 'screenshot' && args.screenshotOptions) {
|
|
156
|
+
const ssOpts = args.screenshotOptions;
|
|
157
|
+
result.push({ type: 'screenshot', ...ssOpts });
|
|
158
|
+
}
|
|
159
|
+
else {
|
|
160
|
+
result.push(fmt);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
return result;
|
|
164
|
+
}
|
|
165
|
+
function buildParsersArray(args) {
|
|
166
|
+
const parsers = args.parsers;
|
|
167
|
+
if (!parsers || parsers.length === 0)
|
|
168
|
+
return undefined;
|
|
169
|
+
const result = [];
|
|
170
|
+
for (const p of parsers) {
|
|
171
|
+
if (p === 'pdf' && args.pdfOptions) {
|
|
172
|
+
const pdfOpts = args.pdfOptions;
|
|
173
|
+
result.push({ type: 'pdf', ...pdfOpts });
|
|
174
|
+
}
|
|
175
|
+
else {
|
|
176
|
+
result.push(p);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
return result;
|
|
180
|
+
}
|
|
181
|
+
function buildWebhook(args) {
|
|
182
|
+
const webhook = args.webhook;
|
|
183
|
+
if (!webhook)
|
|
184
|
+
return undefined;
|
|
185
|
+
const headers = args.webhookHeaders;
|
|
186
|
+
if (headers && Object.keys(headers).length > 0) {
|
|
187
|
+
return { url: webhook, headers };
|
|
188
|
+
}
|
|
189
|
+
return webhook;
|
|
190
|
+
}
|
|
191
|
+
function transformScrapeParams(args) {
|
|
192
|
+
const out = { ...args };
|
|
193
|
+
const formats = buildFormatsArray(out);
|
|
194
|
+
if (formats)
|
|
195
|
+
out.formats = formats;
|
|
196
|
+
const parsers = buildParsersArray(out);
|
|
197
|
+
if (parsers)
|
|
198
|
+
out.parsers = parsers;
|
|
199
|
+
delete out.jsonOptions;
|
|
200
|
+
delete out.screenshotOptions;
|
|
201
|
+
delete out.pdfOptions;
|
|
202
|
+
return out;
|
|
203
|
+
}
|
|
145
204
|
const scrapeParamsSchema = z.object({
|
|
146
205
|
url: z.string().url(),
|
|
147
206
|
formats: z
|
|
148
|
-
.array(z.
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
]),
|
|
159
|
-
z.object({
|
|
160
|
-
type: z.literal('json'),
|
|
161
|
-
prompt: z.string().optional(),
|
|
162
|
-
schema: z.record(z.string(), z.any()).optional(),
|
|
163
|
-
}),
|
|
164
|
-
z.object({
|
|
165
|
-
type: z.literal('screenshot'),
|
|
166
|
-
fullPage: z.boolean().optional(),
|
|
167
|
-
quality: z.number().optional(),
|
|
168
|
-
viewport: z
|
|
169
|
-
.object({ width: z.number(), height: z.number() })
|
|
170
|
-
.optional(),
|
|
171
|
-
}),
|
|
207
|
+
.array(z.enum([
|
|
208
|
+
'markdown',
|
|
209
|
+
'html',
|
|
210
|
+
'rawHtml',
|
|
211
|
+
'screenshot',
|
|
212
|
+
'links',
|
|
213
|
+
'summary',
|
|
214
|
+
'changeTracking',
|
|
215
|
+
'branding',
|
|
216
|
+
'json',
|
|
172
217
|
]))
|
|
173
218
|
.optional(),
|
|
174
|
-
|
|
175
|
-
.
|
|
176
|
-
z.
|
|
177
|
-
z.
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
219
|
+
jsonOptions: z
|
|
220
|
+
.object({
|
|
221
|
+
prompt: z.string().optional(),
|
|
222
|
+
schema: z.record(z.string(), z.any()).optional(),
|
|
223
|
+
})
|
|
224
|
+
.optional(),
|
|
225
|
+
screenshotOptions: z
|
|
226
|
+
.object({
|
|
227
|
+
fullPage: z.boolean().optional(),
|
|
228
|
+
quality: z.number().optional(),
|
|
229
|
+
viewport: z
|
|
230
|
+
.object({ width: z.number(), height: z.number() })
|
|
231
|
+
.optional(),
|
|
232
|
+
})
|
|
233
|
+
.optional(),
|
|
234
|
+
parsers: z.array(z.enum(['pdf'])).optional(),
|
|
235
|
+
pdfOptions: z
|
|
236
|
+
.object({
|
|
237
|
+
maxPages: z.number().int().min(1).max(10000).optional(),
|
|
238
|
+
})
|
|
182
239
|
.optional(),
|
|
183
240
|
onlyMainContent: z.boolean().optional(),
|
|
184
241
|
includeTags: z.array(z.string()).optional(),
|
|
@@ -254,8 +311,8 @@ If JSON extraction returns empty, minimal, or just navigation content, the page
|
|
|
254
311
|
"name": "firecrawl_scrape",
|
|
255
312
|
"arguments": {
|
|
256
313
|
"url": "https://example.com/api-docs",
|
|
257
|
-
"formats": [
|
|
258
|
-
|
|
314
|
+
"formats": ["json"],
|
|
315
|
+
"jsonOptions": {
|
|
259
316
|
"prompt": "Extract the header parameters for the authentication endpoint",
|
|
260
317
|
"schema": {
|
|
261
318
|
"type": "object",
|
|
@@ -274,7 +331,7 @@ If JSON extraction returns empty, minimal, or just navigation content, the page
|
|
|
274
331
|
}
|
|
275
332
|
}
|
|
276
333
|
}
|
|
277
|
-
}
|
|
334
|
+
}
|
|
278
335
|
}
|
|
279
336
|
}
|
|
280
337
|
\`\`\`
|
|
@@ -310,7 +367,8 @@ ${SAFE_MODE
|
|
|
310
367
|
execute: async (args, { session, log }) => {
|
|
311
368
|
const { url, ...options } = args;
|
|
312
369
|
const client = getClient(session);
|
|
313
|
-
const
|
|
370
|
+
const transformed = transformScrapeParams(options);
|
|
371
|
+
const cleaned = removeEmptyTopLevel(transformed);
|
|
314
372
|
log.info('Scraping URL', { url: String(url) });
|
|
315
373
|
const res = await client.scrape(String(url), {
|
|
316
374
|
...cleaned,
|
|
@@ -450,7 +508,11 @@ The query also supports search operators, that you can use if needed to refine t
|
|
|
450
508
|
execute: async (args, { session, log }) => {
|
|
451
509
|
const client = getClient(session);
|
|
452
510
|
const { query, ...opts } = args;
|
|
453
|
-
const
|
|
511
|
+
const searchOpts = { ...opts };
|
|
512
|
+
if (searchOpts.scrapeOptions) {
|
|
513
|
+
searchOpts.scrapeOptions = transformScrapeParams(searchOpts.scrapeOptions);
|
|
514
|
+
}
|
|
515
|
+
const cleaned = removeEmptyTopLevel(searchOpts);
|
|
454
516
|
log.info('Searching', { query: String(query) });
|
|
455
517
|
const res = await client.search(query, {
|
|
456
518
|
...cleaned,
|
|
@@ -504,15 +566,8 @@ server.addTool({
|
|
|
504
566
|
...(SAFE_MODE
|
|
505
567
|
? {}
|
|
506
568
|
: {
|
|
507
|
-
webhook: z
|
|
508
|
-
|
|
509
|
-
z.string(),
|
|
510
|
-
z.object({
|
|
511
|
-
url: z.string(),
|
|
512
|
-
headers: z.record(z.string(), z.string()).optional(),
|
|
513
|
-
}),
|
|
514
|
-
])
|
|
515
|
-
.optional(),
|
|
569
|
+
webhook: z.string().optional(),
|
|
570
|
+
webhookHeaders: z.record(z.string(), z.string()).optional(),
|
|
516
571
|
}),
|
|
517
572
|
deduplicateSimilarURLs: z.boolean().optional(),
|
|
518
573
|
ignoreQueryParameters: z.boolean().optional(),
|
|
@@ -521,7 +576,15 @@ server.addTool({
|
|
|
521
576
|
execute: async (args, { session, log }) => {
|
|
522
577
|
const { url, ...options } = args;
|
|
523
578
|
const client = getClient(session);
|
|
524
|
-
const
|
|
579
|
+
const opts = { ...options };
|
|
580
|
+
if (opts.scrapeOptions) {
|
|
581
|
+
opts.scrapeOptions = transformScrapeParams(opts.scrapeOptions);
|
|
582
|
+
}
|
|
583
|
+
const webhook = buildWebhook(opts);
|
|
584
|
+
if (webhook)
|
|
585
|
+
opts.webhook = webhook;
|
|
586
|
+
delete opts.webhookHeaders;
|
|
587
|
+
const cleaned = removeEmptyTopLevel(opts);
|
|
525
588
|
log.info('Starting crawl', { url: String(url) });
|
|
526
589
|
const res = await client.crawl(String(url), {
|
|
527
590
|
...cleaned,
|
|
@@ -750,21 +813,26 @@ Check the status of an agent job and retrieve results when complete. Use this to
|
|
|
750
813
|
server.addTool({
|
|
751
814
|
name: 'firecrawl_browser_create',
|
|
752
815
|
description: `
|
|
753
|
-
Create a
|
|
816
|
+
Create a browser session for code execution via CDP (Chrome DevTools Protocol).
|
|
754
817
|
|
|
755
|
-
**Best for:** Running code (Python/JS) that interacts with a live browser page, multi-step browser automation,
|
|
818
|
+
**Best for:** Running code (Python/JS) that interacts with a live browser page, multi-step browser automation, sessions with profiles that survive across multiple tool calls.
|
|
756
819
|
**Not recommended for:** Simple page scraping (use firecrawl_scrape instead).
|
|
757
820
|
|
|
758
821
|
**Arguments:**
|
|
759
822
|
- ttl: Total session lifetime in seconds (30-3600, optional)
|
|
760
823
|
- activityTtl: Idle timeout in seconds (10-3600, optional)
|
|
761
824
|
- streamWebView: Whether to enable live view streaming (optional)
|
|
825
|
+
- profile: Save and reuse browser state (cookies, localStorage) across sessions (optional)
|
|
826
|
+
- name: Profile name (sessions with the same name share state)
|
|
827
|
+
- saveChanges: Whether to save changes back to the profile (default: true)
|
|
762
828
|
|
|
763
829
|
**Usage Example:**
|
|
764
830
|
\`\`\`json
|
|
765
831
|
{
|
|
766
832
|
"name": "firecrawl_browser_create",
|
|
767
|
-
"arguments": {
|
|
833
|
+
"arguments": {
|
|
834
|
+
"profile": { "name": "my-profile", "saveChanges": true }
|
|
835
|
+
}
|
|
768
836
|
}
|
|
769
837
|
\`\`\`
|
|
770
838
|
**Returns:** Session ID, CDP URL, and live view URL.
|
|
@@ -773,6 +841,10 @@ Create a persistent browser session for code execution via CDP (Chrome DevTools
|
|
|
773
841
|
ttl: z.number().min(30).max(3600).optional(),
|
|
774
842
|
activityTtl: z.number().min(10).max(3600).optional(),
|
|
775
843
|
streamWebView: z.boolean().optional(),
|
|
844
|
+
profile: z.object({
|
|
845
|
+
name: z.string().min(1).max(128),
|
|
846
|
+
saveChanges: z.boolean().default(true),
|
|
847
|
+
}).optional(),
|
|
776
848
|
}),
|
|
777
849
|
execute: async (args, { session, log }) => {
|
|
778
850
|
const client = getClient(session);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "firecrawl-mcp",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.10.2",
|
|
4
4
|
"description": "MCP server for Firecrawl web scraping integration. Supports both cloud and self-hosted instances. Features include web scraping, search, batch processing, structured data extraction, and LLM-powered content analysis.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"mcpName": "io.github.firecrawl/firecrawl-mcp-server",
|