firecrawl-mcp 3.31.1 → 3.32.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 +3 -0
- package/dist/index.js +47 -8
- package/dist/integration.js +19 -0
- package/dist/server.d.ts +2 -0
- package/dist/server.js +45 -7
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -273,6 +273,9 @@ Optionally, you can add it to a file called `.vscode/mcp.json` in your workspace
|
|
|
273
273
|
- `FIRECRAWL_API_URL` (Optional): Custom API endpoint for self-hosted instances
|
|
274
274
|
- Example: `https://firecrawl.your-domain.com`
|
|
275
275
|
- If not provided, the cloud API will be used (requires API key)
|
|
276
|
+
- `FIRECRAWL_INTEGRATION` (Optional): Integration tag for apps that launch this server, such as an editor extension
|
|
277
|
+
- Sent as the `integration` field of scrape, batch scrape, crawl, map, search, extract, agent, parse, interact and feedback requests
|
|
278
|
+
- Use a value that starts with `_`, for example `_zed`
|
|
276
279
|
|
|
277
280
|
#### MCP OAuth (Bearer access tokens)
|
|
278
281
|
|
package/dist/index.js
CHANGED
|
@@ -3559,6 +3559,22 @@ The historical view returns periods sorted by start date with \`startDate\`, \`e
|
|
|
3559
3559
|
});
|
|
3560
3560
|
}
|
|
3561
3561
|
|
|
3562
|
+
// src/integration.ts
|
|
3563
|
+
var TAGGED_PATH = /^\/v2\/(scrape|batch\/scrape|crawl|map|search|extract|agent|parse|feedback|scrape\/[^/]+\/interact|search\/[^/]+\/feedback)$/;
|
|
3564
|
+
function integrationFrom(value) {
|
|
3565
|
+
const tag = (value ?? "").trim();
|
|
3566
|
+
return tag === "" ? void 0 : tag;
|
|
3567
|
+
}
|
|
3568
|
+
function pathOf(url) {
|
|
3569
|
+
const path2 = url.replace(/^[a-z][a-z0-9+.-]*:\/\/[^/]+/i, "").split(/[?#]/)[0];
|
|
3570
|
+
return path2.replace(/\/+$/, "");
|
|
3571
|
+
}
|
|
3572
|
+
function withIntegration(url, body, integration) {
|
|
3573
|
+
if (!integration || body.integration != null) return body;
|
|
3574
|
+
if (!TAGGED_PATH.test(pathOf(url))) return body;
|
|
3575
|
+
return { ...body, integration };
|
|
3576
|
+
}
|
|
3577
|
+
|
|
3562
3578
|
// src/headers.ts
|
|
3563
3579
|
function normalizeHeader(value) {
|
|
3564
3580
|
if (value == null) return void 0;
|
|
@@ -3999,7 +4015,8 @@ function createFirecrawlMcpServer(options2 = {}) {
|
|
|
3999
4015
|
fileAccess: options2.fileAccess ?? "local",
|
|
4000
4016
|
requireCredential: options2.requireCredential ?? false,
|
|
4001
4017
|
searchFeedback: options2.searchFeedback ?? true,
|
|
4002
|
-
endpointFeedback: options2.endpointFeedback ?? true
|
|
4018
|
+
endpointFeedback: options2.endpointFeedback ?? true,
|
|
4019
|
+
integration: integrationFrom(options2.integration)
|
|
4003
4020
|
};
|
|
4004
4021
|
const logging = options2.logging ?? config.transport === "httpStream";
|
|
4005
4022
|
const instructionDefaults = {
|
|
@@ -4127,7 +4144,22 @@ function createFirecrawlMcpServer(options2 = {}) {
|
|
|
4127
4144
|
if (apiKey2) {
|
|
4128
4145
|
clientConfig.apiKey = apiKey2;
|
|
4129
4146
|
}
|
|
4130
|
-
|
|
4147
|
+
const client = new FirecrawlApp(clientConfig);
|
|
4148
|
+
if (config.integration) {
|
|
4149
|
+
client.http?.instance?.interceptors?.request?.use((request) => {
|
|
4150
|
+
const isPost = String(request.method ?? "").toLowerCase() === "post";
|
|
4151
|
+
const isPlainObject = request.data != null && typeof request.data === "object" && !Array.isArray(request.data) && !(request.data instanceof FormData);
|
|
4152
|
+
if (isPost && isPlainObject) {
|
|
4153
|
+
request.data = withIntegration(
|
|
4154
|
+
request.url ?? "",
|
|
4155
|
+
request.data,
|
|
4156
|
+
config.integration
|
|
4157
|
+
);
|
|
4158
|
+
}
|
|
4159
|
+
return request;
|
|
4160
|
+
});
|
|
4161
|
+
}
|
|
4162
|
+
return client;
|
|
4131
4163
|
}
|
|
4132
4164
|
const SAFE_MODE = config.safeMode;
|
|
4133
4165
|
function getClient(session) {
|
|
@@ -4461,7 +4493,7 @@ function createFirecrawlMcpServer(options2 = {}) {
|
|
|
4461
4493
|
function buildParseOptionsPayload(options3, origin) {
|
|
4462
4494
|
const transformed = transformScrapeParams(options3);
|
|
4463
4495
|
const cleaned = removeEmptyTopLevel(transformed);
|
|
4464
|
-
return { origin, ...cleaned };
|
|
4496
|
+
return withIntegration("/v2/parse", { origin, ...cleaned }, config.integration);
|
|
4465
4497
|
}
|
|
4466
4498
|
function buildContinuationArguments(uploadRef, options3) {
|
|
4467
4499
|
return {
|
|
@@ -4485,7 +4517,7 @@ function createFirecrawlMcpServer(options2 = {}) {
|
|
|
4485
4517
|
Authorization: `Bearer ${apiKey2}`,
|
|
4486
4518
|
...origin ? originHeaders(origin) : {}
|
|
4487
4519
|
},
|
|
4488
|
-
body: JSON.stringify(body)
|
|
4520
|
+
body: JSON.stringify(withIntegration(pathName, body, config.integration))
|
|
4489
4521
|
});
|
|
4490
4522
|
const responseText = await response.text();
|
|
4491
4523
|
let parsed;
|
|
@@ -4928,7 +4960,7 @@ For a programming question, add \`categories: ["developer"]\`; its hits return i
|
|
|
4928
4960
|
const response = await fetch(`${resolveApiBaseUrl()}${path2}`, {
|
|
4929
4961
|
method: "POST",
|
|
4930
4962
|
headers,
|
|
4931
|
-
body: JSON.stringify(body)
|
|
4963
|
+
body: JSON.stringify(withIntegration(path2, body, config.integration))
|
|
4932
4964
|
});
|
|
4933
4965
|
const json = await response.json().catch(() => ({}));
|
|
4934
4966
|
if (!response.ok) {
|
|
@@ -5098,7 +5130,13 @@ Eligibility is limited to successful searches within the feedback age window. Th
|
|
|
5098
5130
|
const response = await fetch(endpoint, {
|
|
5099
5131
|
method: "POST",
|
|
5100
5132
|
headers,
|
|
5101
|
-
body: JSON.stringify(
|
|
5133
|
+
body: JSON.stringify(
|
|
5134
|
+
withIntegration(
|
|
5135
|
+
`/v2/search/${encodeURIComponent(searchId)}/feedback`,
|
|
5136
|
+
body,
|
|
5137
|
+
config.integration
|
|
5138
|
+
)
|
|
5139
|
+
)
|
|
5102
5140
|
});
|
|
5103
5141
|
const responseText = await response.text();
|
|
5104
5142
|
let parsed;
|
|
@@ -5237,7 +5275,7 @@ Returns submission status, feedback ID, and accounting fields.
|
|
|
5237
5275
|
const response = await fetch(`${apiBase}/v2/feedback`, {
|
|
5238
5276
|
method: "POST",
|
|
5239
5277
|
headers,
|
|
5240
|
-
body: JSON.stringify(body)
|
|
5278
|
+
body: JSON.stringify(withIntegration("/v2/feedback", body, config.integration))
|
|
5241
5279
|
});
|
|
5242
5280
|
const responseText = await response.text();
|
|
5243
5281
|
let parsed;
|
|
@@ -6718,7 +6756,8 @@ var options = {
|
|
|
6718
6756
|
fileAccess: hosted ? "upload" : "local",
|
|
6719
6757
|
requireCredential: hosted,
|
|
6720
6758
|
searchFeedback: !searchFeedbackDisabled,
|
|
6721
|
-
endpointFeedback: !endpointFeedbackDisabled
|
|
6759
|
+
endpointFeedback: !endpointFeedbackDisabled,
|
|
6760
|
+
integration: process.env.FIRECRAWL_INTEGRATION
|
|
6722
6761
|
};
|
|
6723
6762
|
var serviceSettings = { hosted, transport, apiKey, apiUrl };
|
|
6724
6763
|
var primaryHooks = createServiceHooks(primaryProfile, serviceSettings);
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
// src/integration.ts
|
|
2
|
+
var TAGGED_PATH = /^\/v2\/(scrape|batch\/scrape|crawl|map|search|extract|agent|parse|feedback|scrape\/[^/]+\/interact|search\/[^/]+\/feedback)$/;
|
|
3
|
+
function integrationFrom(value) {
|
|
4
|
+
const tag = (value ?? "").trim();
|
|
5
|
+
return tag === "" ? void 0 : tag;
|
|
6
|
+
}
|
|
7
|
+
function pathOf(url) {
|
|
8
|
+
const path = url.replace(/^[a-z][a-z0-9+.-]*:\/\/[^/]+/i, "").split(/[?#]/)[0];
|
|
9
|
+
return path.replace(/\/+$/, "");
|
|
10
|
+
}
|
|
11
|
+
function withIntegration(url, body, integration) {
|
|
12
|
+
if (!integration || body.integration != null) return body;
|
|
13
|
+
if (!TAGGED_PATH.test(pathOf(url))) return body;
|
|
14
|
+
return { ...body, integration };
|
|
15
|
+
}
|
|
16
|
+
export {
|
|
17
|
+
integrationFrom,
|
|
18
|
+
withIntegration
|
|
19
|
+
};
|
package/dist/server.d.ts
CHANGED
|
@@ -420,6 +420,8 @@ interface FirecrawlMcpServerOptions {
|
|
|
420
420
|
searchFeedback?: boolean;
|
|
421
421
|
/** Register firecrawl_feedback. Defaults to true. */
|
|
422
422
|
endpointFeedback?: boolean;
|
|
423
|
+
/** Tag sent as the `integration` field of API requests that accept one, such as `_zed`. */
|
|
424
|
+
integration?: string;
|
|
423
425
|
/** Extension hooks. Unstable: may change in any release. */
|
|
424
426
|
unstable_hooks?: FirecrawlMcpServerHooks;
|
|
425
427
|
}
|
package/dist/server.js
CHANGED
|
@@ -3558,6 +3558,22 @@ The historical view returns periods sorted by start date with \`startDate\`, \`e
|
|
|
3558
3558
|
});
|
|
3559
3559
|
}
|
|
3560
3560
|
|
|
3561
|
+
// src/integration.ts
|
|
3562
|
+
var TAGGED_PATH = /^\/v2\/(scrape|batch\/scrape|crawl|map|search|extract|agent|parse|feedback|scrape\/[^/]+\/interact|search\/[^/]+\/feedback)$/;
|
|
3563
|
+
function integrationFrom(value) {
|
|
3564
|
+
const tag = (value ?? "").trim();
|
|
3565
|
+
return tag === "" ? void 0 : tag;
|
|
3566
|
+
}
|
|
3567
|
+
function pathOf(url) {
|
|
3568
|
+
const path2 = url.replace(/^[a-z][a-z0-9+.-]*:\/\/[^/]+/i, "").split(/[?#]/)[0];
|
|
3569
|
+
return path2.replace(/\/+$/, "");
|
|
3570
|
+
}
|
|
3571
|
+
function withIntegration(url, body, integration) {
|
|
3572
|
+
if (!integration || body.integration != null) return body;
|
|
3573
|
+
if (!TAGGED_PATH.test(pathOf(url))) return body;
|
|
3574
|
+
return { ...body, integration };
|
|
3575
|
+
}
|
|
3576
|
+
|
|
3561
3577
|
// src/headers.ts
|
|
3562
3578
|
function normalizeHeader(value) {
|
|
3563
3579
|
if (value == null) return void 0;
|
|
@@ -3998,7 +4014,8 @@ function createFirecrawlMcpServer(options = {}) {
|
|
|
3998
4014
|
fileAccess: options.fileAccess ?? "local",
|
|
3999
4015
|
requireCredential: options.requireCredential ?? false,
|
|
4000
4016
|
searchFeedback: options.searchFeedback ?? true,
|
|
4001
|
-
endpointFeedback: options.endpointFeedback ?? true
|
|
4017
|
+
endpointFeedback: options.endpointFeedback ?? true,
|
|
4018
|
+
integration: integrationFrom(options.integration)
|
|
4002
4019
|
};
|
|
4003
4020
|
const logging = options.logging ?? config.transport === "httpStream";
|
|
4004
4021
|
const instructionDefaults = {
|
|
@@ -4126,7 +4143,22 @@ function createFirecrawlMcpServer(options = {}) {
|
|
|
4126
4143
|
if (apiKey) {
|
|
4127
4144
|
clientConfig.apiKey = apiKey;
|
|
4128
4145
|
}
|
|
4129
|
-
|
|
4146
|
+
const client = new FirecrawlApp(clientConfig);
|
|
4147
|
+
if (config.integration) {
|
|
4148
|
+
client.http?.instance?.interceptors?.request?.use((request) => {
|
|
4149
|
+
const isPost = String(request.method ?? "").toLowerCase() === "post";
|
|
4150
|
+
const isPlainObject = request.data != null && typeof request.data === "object" && !Array.isArray(request.data) && !(request.data instanceof FormData);
|
|
4151
|
+
if (isPost && isPlainObject) {
|
|
4152
|
+
request.data = withIntegration(
|
|
4153
|
+
request.url ?? "",
|
|
4154
|
+
request.data,
|
|
4155
|
+
config.integration
|
|
4156
|
+
);
|
|
4157
|
+
}
|
|
4158
|
+
return request;
|
|
4159
|
+
});
|
|
4160
|
+
}
|
|
4161
|
+
return client;
|
|
4130
4162
|
}
|
|
4131
4163
|
const SAFE_MODE = config.safeMode;
|
|
4132
4164
|
function getClient(session) {
|
|
@@ -4460,7 +4492,7 @@ function createFirecrawlMcpServer(options = {}) {
|
|
|
4460
4492
|
function buildParseOptionsPayload(options2, origin) {
|
|
4461
4493
|
const transformed = transformScrapeParams(options2);
|
|
4462
4494
|
const cleaned = removeEmptyTopLevel(transformed);
|
|
4463
|
-
return { origin, ...cleaned };
|
|
4495
|
+
return withIntegration("/v2/parse", { origin, ...cleaned }, config.integration);
|
|
4464
4496
|
}
|
|
4465
4497
|
function buildContinuationArguments(uploadRef, options2) {
|
|
4466
4498
|
return {
|
|
@@ -4484,7 +4516,7 @@ function createFirecrawlMcpServer(options = {}) {
|
|
|
4484
4516
|
Authorization: `Bearer ${apiKey}`,
|
|
4485
4517
|
...origin ? originHeaders(origin) : {}
|
|
4486
4518
|
},
|
|
4487
|
-
body: JSON.stringify(body)
|
|
4519
|
+
body: JSON.stringify(withIntegration(pathName, body, config.integration))
|
|
4488
4520
|
});
|
|
4489
4521
|
const responseText = await response.text();
|
|
4490
4522
|
let parsed;
|
|
@@ -4927,7 +4959,7 @@ For a programming question, add \`categories: ["developer"]\`; its hits return i
|
|
|
4927
4959
|
const response = await fetch(`${resolveApiBaseUrl()}${path2}`, {
|
|
4928
4960
|
method: "POST",
|
|
4929
4961
|
headers,
|
|
4930
|
-
body: JSON.stringify(body)
|
|
4962
|
+
body: JSON.stringify(withIntegration(path2, body, config.integration))
|
|
4931
4963
|
});
|
|
4932
4964
|
const json = await response.json().catch(() => ({}));
|
|
4933
4965
|
if (!response.ok) {
|
|
@@ -5097,7 +5129,13 @@ Eligibility is limited to successful searches within the feedback age window. Th
|
|
|
5097
5129
|
const response = await fetch(endpoint, {
|
|
5098
5130
|
method: "POST",
|
|
5099
5131
|
headers,
|
|
5100
|
-
body: JSON.stringify(
|
|
5132
|
+
body: JSON.stringify(
|
|
5133
|
+
withIntegration(
|
|
5134
|
+
`/v2/search/${encodeURIComponent(searchId)}/feedback`,
|
|
5135
|
+
body,
|
|
5136
|
+
config.integration
|
|
5137
|
+
)
|
|
5138
|
+
)
|
|
5101
5139
|
});
|
|
5102
5140
|
const responseText = await response.text();
|
|
5103
5141
|
let parsed;
|
|
@@ -5236,7 +5274,7 @@ Returns submission status, feedback ID, and accounting fields.
|
|
|
5236
5274
|
const response = await fetch(`${apiBase}/v2/feedback`, {
|
|
5237
5275
|
method: "POST",
|
|
5238
5276
|
headers,
|
|
5239
|
-
body: JSON.stringify(body)
|
|
5277
|
+
body: JSON.stringify(withIntegration("/v2/feedback", body, config.integration))
|
|
5240
5278
|
});
|
|
5241
5279
|
const responseText = await response.text();
|
|
5242
5280
|
let parsed;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "firecrawl-mcp",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.32.0",
|
|
4
4
|
"description": "MCP server for Firecrawl — search, scrape, and interact with the web, and search scientific papers. Supports both cloud and self-hosted instances. Features include web search, scraping, page interaction, batch processing, LLM-powered content analysis, and research paper search over biomedical and arXiv literature (PubMed, bioRxiv, medRxiv, arXiv) with citation-graph expansion and full-text reading.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"mcpName": "io.github.firecrawl/firecrawl-mcp-server",
|