firecrawl-mcp 3.30.0 → 3.30.1
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 +5 -3
- package/dist/index.js +62 -16
- package/dist/server.js +60 -14
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1112,14 +1112,16 @@ Start with no arguments for categories, then progressively narrow the catalogue:
|
|
|
1112
1112
|
| --- | --- |
|
|
1113
1113
|
| `{}` | Categories and short descriptions |
|
|
1114
1114
|
| `{"categories":["podcasts"]}` | Providers in that category |
|
|
1115
|
-
| `{"categories":["podcasts"],"providers":["particle"]}` | Compact tool names
|
|
1115
|
+
| `{"categories":["podcasts"],"providers":["particle"]}` | Compact tool names and descriptions |
|
|
1116
1116
|
| `{"providers":["particle"],"capabilities":["podcasts/episodes/search"]}` | Complete selected inputs, constraints, response, and examples |
|
|
1117
1117
|
|
|
1118
1118
|
No group hop is required. Explicit `level` supports `categories`, `providers`,
|
|
1119
1119
|
`groups`, or `tools`; explicit `expand` selects contract sections. `expand: []`
|
|
1120
1120
|
keeps results compact even when selecting a capability. For broad full contracts,
|
|
1121
1121
|
explicitly request `level: "tools"` and `expand: ["options", "response", "examples"]`.
|
|
1122
|
-
URLs provide contextual discovery without fetching the page.
|
|
1122
|
+
URLs provide contextual discovery without fetching the page. Tool results omit
|
|
1123
|
+
per-capability credit prices unless `includeCosts: true` is set; follow-up
|
|
1124
|
+
`nextTool` arguments keep it.
|
|
1123
1125
|
|
|
1124
1126
|
Results are in `data.alexandria[0].data`. Follow an item's `nextTool` by calling
|
|
1125
1127
|
its `name` with its `arguments`; the page's `nextTool` advances pagination.
|
|
@@ -1146,7 +1148,7 @@ These controls require the matching Alexandria API deployment.
|
|
|
1146
1148
|
}
|
|
1147
1149
|
```
|
|
1148
1150
|
|
|
1149
|
-
**Returns:** `{ success, scrape_id, requestId, data: { alexandria: [...], creditsCost } }`. Each item is either a result (`provider`, `capability`, `
|
|
1151
|
+
**Returns:** `{ success, scrape_id, requestId, data: { alexandria: [...], creditsCost } }`. Each item is either a result (`provider`, `capability`, `data`, `records`, `upstreamStatus`) or an `error` with a `code`; the batch never fails as a whole for a provider error and `data.creditsCost` is the total charged for the request. Alexandria error bodies (403 without Alexandria access, and 402/409 billing statuses) are relayed in-band with their `code`.
|
|
1150
1152
|
|
|
1151
1153
|
Execution generates one `x-request-id` and returns it on success or failure. Retry
|
|
1152
1154
|
the identical payload with that `requestId`; do not create a new ID after an
|
package/dist/index.js
CHANGED
|
@@ -2422,7 +2422,8 @@ var findToolsSchema = z5.object({
|
|
|
2422
2422
|
level: z5.enum(["categories", "providers", "groups", "tools"]).optional(),
|
|
2423
2423
|
expand: z5.array(z5.enum(["options", "response", "examples"])).optional().describe('Use ["options", "response"] for inputs and output shape without example payloads; [] keeps results compact. Omit for full contracts on selected capabilities.'),
|
|
2424
2424
|
limit: z5.number().int().min(1).max(100).optional(),
|
|
2425
|
-
offset: z5.number().int().nonnegative().optional()
|
|
2425
|
+
offset: z5.number().int().nonnegative().optional(),
|
|
2426
|
+
includeCosts: z5.boolean().optional().describe("Include per-capability credit prices (creditsCost, perRecord) in tool results.")
|
|
2426
2427
|
}).strict();
|
|
2427
2428
|
var ALEXANDRIA_CATALOGUE_VERTICALS = "companies, people, jobs, finance and filings, public records and government spending, real estate, places and restaurants, retail and prices, package registries and developer data, news, research, and more";
|
|
2428
2429
|
var ALEXANDRIA_CATALOGUE_SENTENCE = "Alexandria is Firecrawl's catalogue of data providers and workflows across " + ALEXANDRIA_CATALOGUE_VERTICALS + "; providers return typed, sourced records through published contracts.";
|
|
@@ -2434,7 +2435,7 @@ function findToolsOptions(args2) {
|
|
|
2434
2435
|
if (level === "categories" && (args2.query || args2.providers?.length || args2.categories?.length || args2.groups?.length || args2.capabilities?.length || args2.urls?.length || args2.expand !== void 0)) {
|
|
2435
2436
|
throw new Error("Category index accepts only level, limit and offset. Select a category to browse providers.");
|
|
2436
2437
|
}
|
|
2437
|
-
const { expand, ...selectors } = args2;
|
|
2438
|
+
const { expand, includeCosts, ...selectors } = args2;
|
|
2438
2439
|
return {
|
|
2439
2440
|
...selectors,
|
|
2440
2441
|
...expand !== void 0 ? { expand } : {},
|
|
@@ -2443,10 +2444,10 @@ function findToolsOptions(args2) {
|
|
|
2443
2444
|
...args2.expand === void 0 && level === "tools" && args2.capabilities?.length ? { expand: ["options", "response", "examples"] } : {}
|
|
2444
2445
|
};
|
|
2445
2446
|
}
|
|
2446
|
-
function withFindToolsNavigation(envelope) {
|
|
2447
|
+
function withFindToolsNavigation(envelope, carry = {}) {
|
|
2447
2448
|
const page = envelope?.data?.alexandria?.[0]?.data;
|
|
2448
2449
|
if (!page || !Array.isArray(page.items)) return envelope;
|
|
2449
|
-
const link = (next) => next?.provider === "firecrawl" && next?.capability === "find-tools" && next.options ? { name: "firecrawl_find_tools", arguments: next.options } : void 0;
|
|
2450
|
+
const link = (next) => next?.provider === "firecrawl" && next?.capability === "find-tools" && next.options ? { name: "firecrawl_find_tools", arguments: { ...next.options, ...carry } } : void 0;
|
|
2450
2451
|
for (const item of page.items) {
|
|
2451
2452
|
if (page.level === "providers" && link(item.next)) {
|
|
2452
2453
|
const selectors = { ...item.next.options };
|
|
@@ -2460,6 +2461,49 @@ function withFindToolsNavigation(envelope) {
|
|
|
2460
2461
|
return envelope;
|
|
2461
2462
|
}
|
|
2462
2463
|
var ALEXANDRIA_SEARCH_INSTRUCTIONS = 'Authenticated search combines web results, semantic tool summaries and domain matches. Use sources: ["alexandria"] for semantic tools only. ' + ALEXANDRIA_SOURCES_OPT_OUT + ' Tool matches describe available structured-data capabilities, not executed data. toolDetail: "compact" (default) returns only provider, capability and description; "summary" adds metadata; "full" includes their input and output contracts. firecrawl_scrape with an alexandria body executes a selected capability; firecrawl_find_tools provides catalogue browsing and full contracts.';
|
|
2464
|
+
var TOOL_PRICE_KEYS = ["creditsCost", "perRecord", "billing", "recordsPerUnit", "zeroDataRetentionCreditsCost"];
|
|
2465
|
+
function withoutToolPrice(tool) {
|
|
2466
|
+
if (!tool || typeof tool !== "object" || Array.isArray(tool)) return tool;
|
|
2467
|
+
const copy = { ...tool };
|
|
2468
|
+
for (const key of TOOL_PRICE_KEYS) delete copy[key];
|
|
2469
|
+
return copy;
|
|
2470
|
+
}
|
|
2471
|
+
function withoutDiscoveredToolPrices(body) {
|
|
2472
|
+
const tools = body?.data?.tools ?? body?.tools;
|
|
2473
|
+
if (!Array.isArray(tools)) return body;
|
|
2474
|
+
return body?.data?.tools ? { ...body, data: { ...body.data, tools: tools.map(withoutToolPrice) } } : { ...body, tools: tools.map(withoutToolPrice) };
|
|
2475
|
+
}
|
|
2476
|
+
function withoutPagePrices(page) {
|
|
2477
|
+
if (!page || typeof page !== "object") return page;
|
|
2478
|
+
return {
|
|
2479
|
+
...page,
|
|
2480
|
+
...Array.isArray(page.items) ? { items: page.items.map(withoutToolPrice) } : {},
|
|
2481
|
+
...Array.isArray(page.relatedTools) ? {
|
|
2482
|
+
relatedTools: page.relatedTools.map((group) => Array.isArray(group?.tools) ? { ...group, tools: group.tools.map((entry) => entry?.tool ? { ...entry, tool: withoutToolPrice(entry.tool) } : withoutToolPrice(entry)) } : group)
|
|
2483
|
+
} : {}
|
|
2484
|
+
};
|
|
2485
|
+
}
|
|
2486
|
+
function withoutResultPrices(body) {
|
|
2487
|
+
const results = body?.data?.alexandria;
|
|
2488
|
+
if (!Array.isArray(results)) return body;
|
|
2489
|
+
return {
|
|
2490
|
+
...body,
|
|
2491
|
+
data: {
|
|
2492
|
+
...body.data,
|
|
2493
|
+
alexandria: results.map((entry) => {
|
|
2494
|
+
const stripped = withoutToolPrice(entry);
|
|
2495
|
+
return entry?.provider === "firecrawl" && entry?.capability === "find-tools" && stripped && typeof stripped === "object" ? { ...stripped, data: withoutPagePrices(entry.data) } : stripped;
|
|
2496
|
+
})
|
|
2497
|
+
}
|
|
2498
|
+
};
|
|
2499
|
+
}
|
|
2500
|
+
function withoutFindToolsPrices(envelope) {
|
|
2501
|
+
const stripped = withoutResultPrices(envelope);
|
|
2502
|
+
if (!stripped?.data || typeof stripped.data !== "object") return stripped;
|
|
2503
|
+
const data = { ...stripped.data };
|
|
2504
|
+
delete data.creditsCost;
|
|
2505
|
+
return { ...stripped, data };
|
|
2506
|
+
}
|
|
2463
2507
|
|
|
2464
2508
|
// src/alexandria-output.ts
|
|
2465
2509
|
var INLINE_TOKEN_BUDGET = 2e4;
|
|
@@ -4562,7 +4606,7 @@ Alexandria mode, on an authenticated session with Alexandria access: \`alexandri
|
|
|
4562
4606
|
},
|
|
4563
4607
|
session
|
|
4564
4608
|
);
|
|
4565
|
-
return structuredText(json?.data ?? json);
|
|
4609
|
+
return structuredText(withoutDiscoveredToolPrices(json?.data ?? json));
|
|
4566
4610
|
}
|
|
4567
4611
|
const client = getClient(session);
|
|
4568
4612
|
const res = await relayTermsRequired(
|
|
@@ -4572,7 +4616,7 @@ Alexandria mode, on an authenticated session with Alexandria access: \`alexandri
|
|
|
4572
4616
|
}),
|
|
4573
4617
|
{ tool: "firecrawl_scrape" }
|
|
4574
4618
|
);
|
|
4575
|
-
return structuredText(res);
|
|
4619
|
+
return structuredText(withoutDiscoveredToolPrices(res));
|
|
4576
4620
|
}
|
|
4577
4621
|
};
|
|
4578
4622
|
server.addTool({
|
|
@@ -4675,7 +4719,7 @@ For a programming question, add \`categories: ["developer"]\`; its hits return i
|
|
|
4675
4719
|
const json = await keylessPost("/v2/search", searchBody, session);
|
|
4676
4720
|
const keylessResponse = { ...json ?? {} };
|
|
4677
4721
|
delete keylessResponse.id;
|
|
4678
|
-
return structuredCompact(keylessResponse);
|
|
4722
|
+
return structuredCompact(withoutDiscoveredToolPrices(keylessResponse));
|
|
4679
4723
|
}
|
|
4680
4724
|
const client = getClient(session);
|
|
4681
4725
|
const postSearch = () => postSearchWithFallback(
|
|
@@ -4685,10 +4729,10 @@ For a programming question, add \`categories: ["developer"]\`; its hits return i
|
|
|
4685
4729
|
);
|
|
4686
4730
|
const context = { tool: "firecrawl_search" };
|
|
4687
4731
|
const httpRes = exchangeSource ? await relayExchangeError(postSearch, context) : await relayTermsRequired(postSearch, context);
|
|
4688
|
-
return structuredCompact(httpRes?.data ?? {});
|
|
4732
|
+
return structuredCompact(withoutDiscoveredToolPrices(httpRes?.data ?? {}));
|
|
4689
4733
|
}
|
|
4690
4734
|
});
|
|
4691
|
-
async function executeExchangeCalls(session, alexandria, suppliedRequestId, timeout, origin = requestOrigin(void 0, session)) {
|
|
4735
|
+
async function executeExchangeCalls(session, alexandria, suppliedRequestId, timeout, origin = requestOrigin(void 0, session), includeCosts = false) {
|
|
4692
4736
|
assertExchangeCredential2(session);
|
|
4693
4737
|
const client = getClient(session);
|
|
4694
4738
|
const requestId = suppliedRequestId ?? randomUUID2();
|
|
@@ -4710,7 +4754,7 @@ For a programming question, add \`categories: ["developer"]\`; its hits return i
|
|
|
4710
4754
|
);
|
|
4711
4755
|
const calls = Array.isArray(alexandria) ? alexandria : [alexandria];
|
|
4712
4756
|
return alexandriaOutput(
|
|
4713
|
-
{ ...response?.data ?? {}, requestId },
|
|
4757
|
+
{ ...includeCosts ? response?.data ?? {} : withoutResultPrices(response?.data ?? {}), requestId },
|
|
4714
4758
|
calls,
|
|
4715
4759
|
async (body, id) => {
|
|
4716
4760
|
const result = await client.http.post(
|
|
@@ -4751,6 +4795,7 @@ For a programming question, add \`categories: ["developer"]\`; its hits return i
|
|
|
4751
4795
|
} catch (error2) {
|
|
4752
4796
|
throw new UserError2(error2 instanceof Error ? error2.message : String(error2));
|
|
4753
4797
|
}
|
|
4798
|
+
const carry = args2.includeCosts ? { includeCosts: true } : {};
|
|
4754
4799
|
if (options3.level === "categories") {
|
|
4755
4800
|
assertExchangeCredential2(session);
|
|
4756
4801
|
const response = await relayExchangeError(
|
|
@@ -4768,11 +4813,12 @@ For a programming question, add \`categories: ["developer"]\`; its hits return i
|
|
|
4768
4813
|
next: { provider: "firecrawl", capability: "find-tools", options: { categories: [row.cohort], level: "providers", limit: options3.limit } }
|
|
4769
4814
|
}));
|
|
4770
4815
|
const page = { level: "categories", items, total: rows.length };
|
|
4771
|
-
if (offset + options3.limit < rows.length) page.nextTool = { name: "firecrawl_find_tools", arguments: { level: "categories", limit: options3.limit, offset: offset + options3.limit } };
|
|
4772
|
-
return structuredCompact(withAlexandriaFeedbackHint(withFindToolsNavigation({ success: true, data: {
|
|
4816
|
+
if (offset + options3.limit < rows.length) page.nextTool = { name: "firecrawl_find_tools", arguments: { level: "categories", limit: options3.limit, offset: offset + options3.limit, ...carry } };
|
|
4817
|
+
return structuredCompact(withAlexandriaFeedbackHint(withFindToolsNavigation({ success: true, data: { alexandria: [{ provider: "firecrawl", capability: "find-tools", data: page }] } }, carry), alexandriaFeedbackAvailable()));
|
|
4773
4818
|
}
|
|
4774
|
-
const result = await executeExchangeCalls(session, { provider: "firecrawl", capability: "find-tools", options: options3 }, void 0, void 0, origin);
|
|
4775
|
-
|
|
4819
|
+
const result = await executeExchangeCalls(session, { provider: "firecrawl", capability: "find-tools", options: options3 }, void 0, void 0, origin, carry.includeCosts);
|
|
4820
|
+
const envelope = JSON.parse(result);
|
|
4821
|
+
return structuredCompact(withFindToolsNavigation(carry.includeCosts ? envelope : withoutFindToolsPrices(envelope), carry));
|
|
4776
4822
|
}
|
|
4777
4823
|
};
|
|
4778
4824
|
server.addTool(findToolsTool);
|
|
@@ -5832,7 +5878,7 @@ function getOAuthIssuer() {
|
|
|
5832
5878
|
normalizeHeader(process.env.FIRECRAWL_OAUTH_ISSUER) ?? DEFAULT_OAUTH_ISSUER
|
|
5833
5879
|
);
|
|
5834
5880
|
}
|
|
5835
|
-
var SEARCH_PROFILE_INSTRUCTIONS = ALEXANDRIA_SEARCH_INSTRUCTIONS + ` Firecrawl provides web, developer, government, and research search, and executes catalogued Alexandria data providers. Use firecrawl_search to find relevant results across the web and specialized indexes; authenticated searches also return matching Alexandria providers in data.tools. firecrawl_find_tools provides catalogue browsing and provider contracts; firecrawl_scrape with an alexandria body executes a selected capability; firecrawl_scrape with a url retrieves one supplied page. For a programming question, firecrawl_developer_search searches indexed public repositories, GitHub issues, merged pull requests, READMEs, and code documentation and returns the matched passages, and skills: "only" narrows it to agent-skill files; firecrawl_search with categories: ["developer"] reaches the same index beside ordinary web results, returning the hits in the web group rather than as passages and offering no skills filter. For a legal or regulatory question, firecrawl_gov_search searches primary law and regulatory material from US federal, state, and local government sources: statutes, regulations, codes, court opinions, and other government publications; firecrawl_search with categories: ["gov"] reaches the same sources in the web group and cannot be combined with other categories. For a biomedical, life-science, clinical, or arXiv literature question, the firecrawl_research_* tools search the paper index, while categories: ["research"] on firecrawl_search filters ordinary web results to research-affiliated websites. Use the firecrawl_research_* tools to search academic and research literature, expand from anchor papers via the citation graph, and read full-text passages from a specific paper. Search and discovery tools are read-only and return ranked results. Billing: web, developer, and research search are billed per request; government search is free; Alexandria discovery (firecrawl_search with sources ["alexandria"] alone, and firecrawl_find_tools) is free; firecrawl_scrape is billed, as a page retrieval in url mode or
|
|
5881
|
+
var SEARCH_PROFILE_INSTRUCTIONS = ALEXANDRIA_SEARCH_INSTRUCTIONS + ` Firecrawl provides web, developer, government, and research search, and executes catalogued Alexandria data providers. Use firecrawl_search to find relevant results across the web and specialized indexes; authenticated searches also return matching Alexandria providers in data.tools. firecrawl_find_tools provides catalogue browsing and provider contracts; firecrawl_scrape with an alexandria body executes a selected capability; firecrawl_scrape with a url retrieves one supplied page. For a programming question, firecrawl_developer_search searches indexed public repositories, GitHub issues, merged pull requests, READMEs, and code documentation and returns the matched passages, and skills: "only" narrows it to agent-skill files; firecrawl_search with categories: ["developer"] reaches the same index beside ordinary web results, returning the hits in the web group rather than as passages and offering no skills filter. For a legal or regulatory question, firecrawl_gov_search searches primary law and regulatory material from US federal, state, and local government sources: statutes, regulations, codes, court opinions, and other government publications; firecrawl_search with categories: ["gov"] reaches the same sources in the web group and cannot be combined with other categories. For a biomedical, life-science, clinical, or arXiv literature question, the firecrawl_research_* tools search the paper index, while categories: ["research"] on firecrawl_search filters ordinary web results to research-affiliated websites. Use the firecrawl_research_* tools to search academic and research literature, expand from anchor papers via the citation graph, and read full-text passages from a specific paper. Search and discovery tools are read-only and return ranked results. Billing: web, developer, and research search are billed per request; government search is free; Alexandria discovery (firecrawl_search with sources ["alexandria"] alone, and firecrawl_find_tools) is free; firecrawl_scrape is billed, as a page retrieval in url mode or per executed capability in alexandria mode (pass includeCosts to firecrawl_find_tools to see prices).`;
|
|
5836
5882
|
var SEARCH_PROFILE_TOOLS = /* @__PURE__ */ new Set([
|
|
5837
5883
|
"firecrawl_search",
|
|
5838
5884
|
"firecrawl_developer_search",
|
|
@@ -6341,7 +6387,7 @@ Scrape one URL and return its content, or execute catalogued Alexandria capabili
|
|
|
6341
6387
|
|
|
6342
6388
|
\`firecrawl_search\` with \`sources\` unset and \`firecrawl_find_tools\` can discover providers for the same fields across several pages; a matching Alexandria provider returns typed records in one call.
|
|
6343
6389
|
|
|
6344
|
-
Alexandria mode: \`alexandria\` selects catalogued capability execution and is mutually exclusive with \`url\`. Alexandria execution is billed
|
|
6390
|
+
Alexandria mode: \`alexandria\` selects catalogued capability execution and is mutually exclusive with \`url\`. Alexandria execution is billed per capability (pass includeCosts to firecrawl_find_tools to see prices if you need) and needs a team with Alexandria enabled.
|
|
6345
6391
|
`;
|
|
6346
6392
|
}
|
|
6347
6393
|
var SEARCH_SURFACE_FIND_TOOLS_DESCRIPTION = "Browse Alexandria data providers and workflows or read a selected contract. Alexandria covers " + ALEXANDRIA_CATALOGUE_VERTICALS + ": typed, sourced records through published contracts. Prefer normal firecrawl_search for a data task; it already returns matching providers. Use this tool when the contract you need was not returned in full, to browse a category when search found nothing, or before scraping the same fields from several pages. Discovery is free. Use query for semantic discovery or urls to find providers for a website. With no arguments, browse categories, then providers and tools. Contracts describe the inputs and outputs for execution through firecrawl_scrape. nextTool identifies further discovery or pagination. Discovery does not execute providers. Use firecrawl_search when you also need web results.";
|
package/dist/server.js
CHANGED
|
@@ -2417,7 +2417,8 @@ var findToolsSchema = z5.object({
|
|
|
2417
2417
|
level: z5.enum(["categories", "providers", "groups", "tools"]).optional(),
|
|
2418
2418
|
expand: z5.array(z5.enum(["options", "response", "examples"])).optional().describe('Use ["options", "response"] for inputs and output shape without example payloads; [] keeps results compact. Omit for full contracts on selected capabilities.'),
|
|
2419
2419
|
limit: z5.number().int().min(1).max(100).optional(),
|
|
2420
|
-
offset: z5.number().int().nonnegative().optional()
|
|
2420
|
+
offset: z5.number().int().nonnegative().optional(),
|
|
2421
|
+
includeCosts: z5.boolean().optional().describe("Include per-capability credit prices (creditsCost, perRecord) in tool results.")
|
|
2421
2422
|
}).strict();
|
|
2422
2423
|
var ALEXANDRIA_CATALOGUE_VERTICALS = "companies, people, jobs, finance and filings, public records and government spending, real estate, places and restaurants, retail and prices, package registries and developer data, news, research, and more";
|
|
2423
2424
|
var ALEXANDRIA_CATALOGUE_SENTENCE = "Alexandria is Firecrawl's catalogue of data providers and workflows across " + ALEXANDRIA_CATALOGUE_VERTICALS + "; providers return typed, sourced records through published contracts.";
|
|
@@ -2429,7 +2430,7 @@ function findToolsOptions(args) {
|
|
|
2429
2430
|
if (level === "categories" && (args.query || args.providers?.length || args.categories?.length || args.groups?.length || args.capabilities?.length || args.urls?.length || args.expand !== void 0)) {
|
|
2430
2431
|
throw new Error("Category index accepts only level, limit and offset. Select a category to browse providers.");
|
|
2431
2432
|
}
|
|
2432
|
-
const { expand, ...selectors } = args;
|
|
2433
|
+
const { expand, includeCosts, ...selectors } = args;
|
|
2433
2434
|
return {
|
|
2434
2435
|
...selectors,
|
|
2435
2436
|
...expand !== void 0 ? { expand } : {},
|
|
@@ -2438,10 +2439,10 @@ function findToolsOptions(args) {
|
|
|
2438
2439
|
...args.expand === void 0 && level === "tools" && args.capabilities?.length ? { expand: ["options", "response", "examples"] } : {}
|
|
2439
2440
|
};
|
|
2440
2441
|
}
|
|
2441
|
-
function withFindToolsNavigation(envelope) {
|
|
2442
|
+
function withFindToolsNavigation(envelope, carry = {}) {
|
|
2442
2443
|
const page = envelope?.data?.alexandria?.[0]?.data;
|
|
2443
2444
|
if (!page || !Array.isArray(page.items)) return envelope;
|
|
2444
|
-
const link = (next) => next?.provider === "firecrawl" && next?.capability === "find-tools" && next.options ? { name: "firecrawl_find_tools", arguments: next.options } : void 0;
|
|
2445
|
+
const link = (next) => next?.provider === "firecrawl" && next?.capability === "find-tools" && next.options ? { name: "firecrawl_find_tools", arguments: { ...next.options, ...carry } } : void 0;
|
|
2445
2446
|
for (const item of page.items) {
|
|
2446
2447
|
if (page.level === "providers" && link(item.next)) {
|
|
2447
2448
|
const selectors = { ...item.next.options };
|
|
@@ -2455,6 +2456,49 @@ function withFindToolsNavigation(envelope) {
|
|
|
2455
2456
|
return envelope;
|
|
2456
2457
|
}
|
|
2457
2458
|
var ALEXANDRIA_SEARCH_INSTRUCTIONS = 'Authenticated search combines web results, semantic tool summaries and domain matches. Use sources: ["alexandria"] for semantic tools only. ' + ALEXANDRIA_SOURCES_OPT_OUT + ' Tool matches describe available structured-data capabilities, not executed data. toolDetail: "compact" (default) returns only provider, capability and description; "summary" adds metadata; "full" includes their input and output contracts. firecrawl_scrape with an alexandria body executes a selected capability; firecrawl_find_tools provides catalogue browsing and full contracts.';
|
|
2459
|
+
var TOOL_PRICE_KEYS = ["creditsCost", "perRecord", "billing", "recordsPerUnit", "zeroDataRetentionCreditsCost"];
|
|
2460
|
+
function withoutToolPrice(tool) {
|
|
2461
|
+
if (!tool || typeof tool !== "object" || Array.isArray(tool)) return tool;
|
|
2462
|
+
const copy = { ...tool };
|
|
2463
|
+
for (const key of TOOL_PRICE_KEYS) delete copy[key];
|
|
2464
|
+
return copy;
|
|
2465
|
+
}
|
|
2466
|
+
function withoutDiscoveredToolPrices(body) {
|
|
2467
|
+
const tools = body?.data?.tools ?? body?.tools;
|
|
2468
|
+
if (!Array.isArray(tools)) return body;
|
|
2469
|
+
return body?.data?.tools ? { ...body, data: { ...body.data, tools: tools.map(withoutToolPrice) } } : { ...body, tools: tools.map(withoutToolPrice) };
|
|
2470
|
+
}
|
|
2471
|
+
function withoutPagePrices(page) {
|
|
2472
|
+
if (!page || typeof page !== "object") return page;
|
|
2473
|
+
return {
|
|
2474
|
+
...page,
|
|
2475
|
+
...Array.isArray(page.items) ? { items: page.items.map(withoutToolPrice) } : {},
|
|
2476
|
+
...Array.isArray(page.relatedTools) ? {
|
|
2477
|
+
relatedTools: page.relatedTools.map((group) => Array.isArray(group?.tools) ? { ...group, tools: group.tools.map((entry) => entry?.tool ? { ...entry, tool: withoutToolPrice(entry.tool) } : withoutToolPrice(entry)) } : group)
|
|
2478
|
+
} : {}
|
|
2479
|
+
};
|
|
2480
|
+
}
|
|
2481
|
+
function withoutResultPrices(body) {
|
|
2482
|
+
const results = body?.data?.alexandria;
|
|
2483
|
+
if (!Array.isArray(results)) return body;
|
|
2484
|
+
return {
|
|
2485
|
+
...body,
|
|
2486
|
+
data: {
|
|
2487
|
+
...body.data,
|
|
2488
|
+
alexandria: results.map((entry) => {
|
|
2489
|
+
const stripped = withoutToolPrice(entry);
|
|
2490
|
+
return entry?.provider === "firecrawl" && entry?.capability === "find-tools" && stripped && typeof stripped === "object" ? { ...stripped, data: withoutPagePrices(entry.data) } : stripped;
|
|
2491
|
+
})
|
|
2492
|
+
}
|
|
2493
|
+
};
|
|
2494
|
+
}
|
|
2495
|
+
function withoutFindToolsPrices(envelope) {
|
|
2496
|
+
const stripped = withoutResultPrices(envelope);
|
|
2497
|
+
if (!stripped?.data || typeof stripped.data !== "object") return stripped;
|
|
2498
|
+
const data = { ...stripped.data };
|
|
2499
|
+
delete data.creditsCost;
|
|
2500
|
+
return { ...stripped, data };
|
|
2501
|
+
}
|
|
2458
2502
|
|
|
2459
2503
|
// src/alexandria-output.ts
|
|
2460
2504
|
var INLINE_TOKEN_BUDGET = 2e4;
|
|
@@ -4557,7 +4601,7 @@ Alexandria mode, on an authenticated session with Alexandria access: \`alexandri
|
|
|
4557
4601
|
},
|
|
4558
4602
|
session
|
|
4559
4603
|
);
|
|
4560
|
-
return structuredText(json?.data ?? json);
|
|
4604
|
+
return structuredText(withoutDiscoveredToolPrices(json?.data ?? json));
|
|
4561
4605
|
}
|
|
4562
4606
|
const client = getClient(session);
|
|
4563
4607
|
const res = await relayTermsRequired(
|
|
@@ -4567,7 +4611,7 @@ Alexandria mode, on an authenticated session with Alexandria access: \`alexandri
|
|
|
4567
4611
|
}),
|
|
4568
4612
|
{ tool: "firecrawl_scrape" }
|
|
4569
4613
|
);
|
|
4570
|
-
return structuredText(res);
|
|
4614
|
+
return structuredText(withoutDiscoveredToolPrices(res));
|
|
4571
4615
|
}
|
|
4572
4616
|
};
|
|
4573
4617
|
server.addTool({
|
|
@@ -4670,7 +4714,7 @@ For a programming question, add \`categories: ["developer"]\`; its hits return i
|
|
|
4670
4714
|
const json = await keylessPost("/v2/search", searchBody, session);
|
|
4671
4715
|
const keylessResponse = { ...json ?? {} };
|
|
4672
4716
|
delete keylessResponse.id;
|
|
4673
|
-
return structuredCompact(keylessResponse);
|
|
4717
|
+
return structuredCompact(withoutDiscoveredToolPrices(keylessResponse));
|
|
4674
4718
|
}
|
|
4675
4719
|
const client = getClient(session);
|
|
4676
4720
|
const postSearch = () => postSearchWithFallback(
|
|
@@ -4680,10 +4724,10 @@ For a programming question, add \`categories: ["developer"]\`; its hits return i
|
|
|
4680
4724
|
);
|
|
4681
4725
|
const context = { tool: "firecrawl_search" };
|
|
4682
4726
|
const httpRes = exchangeSource ? await relayExchangeError(postSearch, context) : await relayTermsRequired(postSearch, context);
|
|
4683
|
-
return structuredCompact(httpRes?.data ?? {});
|
|
4727
|
+
return structuredCompact(withoutDiscoveredToolPrices(httpRes?.data ?? {}));
|
|
4684
4728
|
}
|
|
4685
4729
|
});
|
|
4686
|
-
async function executeExchangeCalls(session, alexandria, suppliedRequestId, timeout, origin = requestOrigin(void 0, session)) {
|
|
4730
|
+
async function executeExchangeCalls(session, alexandria, suppliedRequestId, timeout, origin = requestOrigin(void 0, session), includeCosts = false) {
|
|
4687
4731
|
assertExchangeCredential2(session);
|
|
4688
4732
|
const client = getClient(session);
|
|
4689
4733
|
const requestId = suppliedRequestId ?? randomUUID2();
|
|
@@ -4705,7 +4749,7 @@ For a programming question, add \`categories: ["developer"]\`; its hits return i
|
|
|
4705
4749
|
);
|
|
4706
4750
|
const calls = Array.isArray(alexandria) ? alexandria : [alexandria];
|
|
4707
4751
|
return alexandriaOutput(
|
|
4708
|
-
{ ...response?.data ?? {}, requestId },
|
|
4752
|
+
{ ...includeCosts ? response?.data ?? {} : withoutResultPrices(response?.data ?? {}), requestId },
|
|
4709
4753
|
calls,
|
|
4710
4754
|
async (body, id) => {
|
|
4711
4755
|
const result = await client.http.post(
|
|
@@ -4746,6 +4790,7 @@ For a programming question, add \`categories: ["developer"]\`; its hits return i
|
|
|
4746
4790
|
} catch (error2) {
|
|
4747
4791
|
throw new UserError2(error2 instanceof Error ? error2.message : String(error2));
|
|
4748
4792
|
}
|
|
4793
|
+
const carry = args.includeCosts ? { includeCosts: true } : {};
|
|
4749
4794
|
if (options2.level === "categories") {
|
|
4750
4795
|
assertExchangeCredential2(session);
|
|
4751
4796
|
const response = await relayExchangeError(
|
|
@@ -4763,11 +4808,12 @@ For a programming question, add \`categories: ["developer"]\`; its hits return i
|
|
|
4763
4808
|
next: { provider: "firecrawl", capability: "find-tools", options: { categories: [row.cohort], level: "providers", limit: options2.limit } }
|
|
4764
4809
|
}));
|
|
4765
4810
|
const page = { level: "categories", items, total: rows.length };
|
|
4766
|
-
if (offset + options2.limit < rows.length) page.nextTool = { name: "firecrawl_find_tools", arguments: { level: "categories", limit: options2.limit, offset: offset + options2.limit } };
|
|
4767
|
-
return structuredCompact(withAlexandriaFeedbackHint(withFindToolsNavigation({ success: true, data: {
|
|
4811
|
+
if (offset + options2.limit < rows.length) page.nextTool = { name: "firecrawl_find_tools", arguments: { level: "categories", limit: options2.limit, offset: offset + options2.limit, ...carry } };
|
|
4812
|
+
return structuredCompact(withAlexandriaFeedbackHint(withFindToolsNavigation({ success: true, data: { alexandria: [{ provider: "firecrawl", capability: "find-tools", data: page }] } }, carry), alexandriaFeedbackAvailable()));
|
|
4768
4813
|
}
|
|
4769
|
-
const result = await executeExchangeCalls(session, { provider: "firecrawl", capability: "find-tools", options: options2 }, void 0, void 0, origin);
|
|
4770
|
-
|
|
4814
|
+
const result = await executeExchangeCalls(session, { provider: "firecrawl", capability: "find-tools", options: options2 }, void 0, void 0, origin, carry.includeCosts);
|
|
4815
|
+
const envelope = JSON.parse(result);
|
|
4816
|
+
return structuredCompact(withFindToolsNavigation(carry.includeCosts ? envelope : withoutFindToolsPrices(envelope), carry));
|
|
4771
4817
|
}
|
|
4772
4818
|
};
|
|
4773
4819
|
server.addTool(findToolsTool);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "firecrawl-mcp",
|
|
3
|
-
"version": "3.30.
|
|
3
|
+
"version": "3.30.1",
|
|
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",
|