firecrawl-mcp 3.30.2 → 3.30.3

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/dist/index.js CHANGED
@@ -2401,6 +2401,14 @@ function defaultDomainTools(sources) {
2401
2401
  (source) => ["web", "news", "images"].includes(typeof source === "string" ? source : source?.type)
2402
2402
  );
2403
2403
  }
2404
+ function withAlexandriaSource(sources) {
2405
+ if (!Array.isArray(sources) || sources.length === 0) return ["web", "alexandria"];
2406
+ if (hasAlexandria(sources)) return sources;
2407
+ return [...sources, typeof sources[0] === "string" ? "alexandria" : { type: "alexandria" }];
2408
+ }
2409
+ function enterpriseAllowsAlexandria(enterprise) {
2410
+ return !(Array.isArray(enterprise) && enterprise.some((mode) => mode === "zdr" || mode === "anon"));
2411
+ }
2404
2412
  function normalizeSearchSources(sources) {
2405
2413
  if (!Array.isArray(sources)) return sources;
2406
2414
  return sources.map(
@@ -2427,8 +2435,8 @@ var findToolsSchema = z5.object({
2427
2435
  }).strict();
2428
2436
  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";
2429
2437
  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.";
2430
- var ALEXANDRIA_SOURCES_OPT_OUT = 'A search with sources: ["web"] omits semantic provider discovery; domainTools: true can still return website-matched tools. Web-only results use domainTools: false.';
2431
- var ALEXANDRIA_SEARCH_LEAD = "Authenticated search also returns matching Alexandria data providers in data.tools (" + ALEXANDRIA_CATALOGUE_VERTICALS + "). Prefer a provider over scraping pages when the task needs the same fields across several entities, exact figures or timestamps, provenance, or many records; use web results when they already answer the question. " + ALEXANDRIA_SOURCES_OPT_OUT;
2438
+ var ALEXANDRIA_SOURCES_ALWAYS_ON = 'Authenticated searches always add alexandria to the sources, so sources: ["web"] also returns providers; domainTools: false turns off website-matched tools only.';
2439
+ var ALEXANDRIA_SEARCH_LEAD = "Authenticated search also returns matching Alexandria data providers in data.tools (" + ALEXANDRIA_CATALOGUE_VERTICALS + "). Prefer a provider over scraping pages when the task needs the same fields across several entities, exact figures or timestamps, provenance, or many records; use web results when they already answer the question. " + ALEXANDRIA_SOURCES_ALWAYS_ON;
2432
2440
  var ALEXANDRIA_CONTRACT_GUIDANCE = "The selected contract marks required inputs and any requiresOneOf groups (at least one member per group); it may include example.request/example.response and response.key (which may differ from records). Where pagination is declared, its fields govern paging with the same filters; catalogue next is separate from provider pagination.";
2433
2441
  function findToolsOptions(args2) {
2434
2442
  const level = args2.level ?? (args2.query || args2.capabilities?.length || args2.providers?.length || args2.groups?.length || args2.urls?.length ? "tools" : args2.categories?.length ? "providers" : "categories");
@@ -2460,7 +2468,7 @@ function withFindToolsNavigation(envelope, carry = {}) {
2460
2468
  if (link(page.next)) page.nextTool = link(page.next);
2461
2469
  return envelope;
2462
2470
  }
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.';
2471
+ var ALEXANDRIA_SEARCH_INSTRUCTIONS = 'Authenticated search combines web results, semantic tool summaries and domain matches. Use sources: ["alexandria"] for semantic tools only. ' + ALEXANDRIA_SOURCES_ALWAYS_ON + ' 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
2472
  var TOOL_PRICE_KEYS = ["creditsCost", "perRecord", "billing", "recordsPerUnit", "zeroDataRetentionCreditsCost"];
2465
2473
  function withoutToolPrice(tool) {
2466
2474
  if (!tool || typeof tool !== "object" || Array.isArray(tool)) return tool;
@@ -3677,7 +3685,7 @@ var searchToolBaseFields = {
3677
3685
  location: z11.string().optional(),
3678
3686
  includeDomains: z11.array(searchDomainSchema).optional().describe("Hostnames to restrict results to. Mutually exclusive with excludeDomains."),
3679
3687
  excludeDomains: z11.array(searchDomainSchema).optional().describe("Hostnames to leave out of results. Mutually exclusive with includeDomains."),
3680
- sources: z11.array(searchSourceSchema).optional().describe("Search sources; authenticated sessions default to web + alexandria, keyless sessions to web only. " + ALEXANDRIA_SOURCES_OPT_OUT + ' Use ["alexandria"] alone for provider discovery without web results.'),
3688
+ sources: z11.array(searchSourceSchema).optional().describe("Search sources; authenticated sessions default to web + alexandria, keyless sessions to web only. " + ALEXANDRIA_SOURCES_ALWAYS_ON + ' enterprise zdr or anon searches do not add it. Use ["alexandria"] alone for provider discovery without web results.'),
3681
3689
  categories: z11.array(z11.enum(["research", "pdf", "developer", "gov"])).optional().describe(
3682
3690
  "Limit results to specific source types. `research` restricts ordinary web results to research-affiliated websites and returns page snippets, which is separate from the `firecrawl_research_*` tools that search paper abstracts and full text across biomedical (PubMed, bioRxiv, medRxiv) and arXiv literature; `pdf` searches PDF results; `developer` searches an index built for coding agents over public repositories, GitHub issues, merged pull requests, repository READMEs, and code documentation; `gov` searches the Government Index of US federal, state, and local legal and regulatory sources, the index behind firecrawl_gov_search, and cannot be combined with other categories; gov hits can include historical versions, bill text, agency guidance, and third-party reproductions, so verify the issuer, jurisdiction, enacted/effective status, and version before citing current governing law, clarify a missing jurisdiction or ambiguous as-of date, and use general search for non-US questions or missing coverage (no hits does not establish that no applicable law exists). `developer` and `gov` return hits in `data.web` with `category` set to their name; the other categories also filter `data.web`."
3683
3691
  ),
@@ -3819,7 +3827,7 @@ async function relayExchangeError(run, context) {
3819
3827
  });
3820
3828
  }
3821
3829
  }
3822
- async function postSearchWithFallback(client, body, implicitTools) {
3830
+ async function postSearchWithFallback(client, body, implicitTools, fallbackSources = ["web"]) {
3823
3831
  try {
3824
3832
  return await client.http.post("/v2/search", body);
3825
3833
  } catch (error2) {
@@ -3832,7 +3840,7 @@ async function postSearchWithFallback(client, body, implicitTools) {
3832
3840
  if (!implicitTools || response?.status !== 403 || !unavailable) throw error2;
3833
3841
  return client.http.post("/v2/search", {
3834
3842
  ...body,
3835
- sources: ["web"],
3843
+ sources: fallbackSources,
3836
3844
  domainTools: false
3837
3845
  });
3838
3846
  }
@@ -3892,7 +3900,7 @@ var ConsoleLogger = class {
3892
3900
  }
3893
3901
  }
3894
3902
  };
3895
- var FULL_PROFILE_INSTRUCTIONS = `Firecrawl provides web search, page retrieval, site URL discovery, multi-page collection, structured page data, monitoring, and multi-source research that returns structured data. Match the requested operation to the tool boundary: firecrawl_scrape retrieves one supplied page and can return JSON matching a supplied schema, firecrawl_map enumerates URLs under a site without retrieving their content, and firecrawl_agent runs multi-source research and returns structured data when the URLs are not known or the answer spans several sites (an entity plus its fields, a list, a dataset); its result is read with firecrawl_agent_status. Authenticated firecrawl_search returns web results together with matching Alexandria providers in data.tools. ${ALEXANDRIA_CATALOGUE_SENTENCE} A matching provider can return the same fields across several entities, provenance, exact figures or timestamps, or a large set of records through firecrawl_scrape with its published contract. If web results already answer the question, use them. For the same fields across multiple pages, firecrawl_find_tools offers free provider discovery. Use firecrawl_find_tools to read a contract that was not returned in full or to browse the catalogue by category. ${ALEXANDRIA_SOURCES_OPT_OUT} If no provider fits, continue with web search or firecrawl_agent. For biomedical, life-science, clinical, or arXiv literature, the firecrawl_research_* tools search a paper index of abstracts and full text; firecrawl_search with categories: ["research"] is a website filter over ordinary web results and reaches different sources. For a programming question (code behaviour, a library or framework, an API contract, an error message, or a known bug), firecrawl_developer_search (or firecrawl_search with categories: ["developer"]) searches an index of public repositories, GitHub issues, merged pull requests, READMEs, and code documentation. 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 and cannot be combined with other categories. firecrawl_search with sources: [{type: "alexandria"}] returns compact tool summaries in data.tools; toolDetail: "full" includes contracts, firecrawl_find_tools starts with categories, lists providers, then compact tools, and expands the selected full contract, and firecrawl_scrape with alexandria: [{provider, capability, options}] executes up to ten capabilities and returns their results. Alexandria access needs an API key on a team with it enabled. Provide only the required inputs and account for stated network or external side effects.`;
3903
+ var FULL_PROFILE_INSTRUCTIONS = `Firecrawl provides web search, page retrieval, site URL discovery, multi-page collection, structured page data, monitoring, and multi-source research that returns structured data. Match the requested operation to the tool boundary: firecrawl_scrape retrieves one supplied page and can return JSON matching a supplied schema, firecrawl_map enumerates URLs under a site without retrieving their content, and firecrawl_agent runs multi-source research and returns structured data when the URLs are not known or the answer spans several sites (an entity plus its fields, a list, a dataset); its result is read with firecrawl_agent_status. Authenticated firecrawl_search returns web results together with matching Alexandria providers in data.tools. ${ALEXANDRIA_CATALOGUE_SENTENCE} A matching provider can return the same fields across several entities, provenance, exact figures or timestamps, or a large set of records through firecrawl_scrape with its published contract. If web results already answer the question, use them. For the same fields across multiple pages, firecrawl_find_tools offers free provider discovery. Use firecrawl_find_tools to read a contract that was not returned in full or to browse the catalogue by category. ${ALEXANDRIA_SOURCES_ALWAYS_ON} If no provider fits, continue with web search or firecrawl_agent. For biomedical, life-science, clinical, or arXiv literature, the firecrawl_research_* tools search a paper index of abstracts and full text; firecrawl_search with categories: ["research"] is a website filter over ordinary web results and reaches different sources. For a programming question (code behaviour, a library or framework, an API contract, an error message, or a known bug), firecrawl_developer_search (or firecrawl_search with categories: ["developer"]) searches an index of public repositories, GitHub issues, merged pull requests, READMEs, and code documentation. 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 and cannot be combined with other categories. firecrawl_search with sources: [{type: "alexandria"}] returns compact tool summaries in data.tools; toolDetail: "full" includes contracts, firecrawl_find_tools starts with categories, lists providers, then compact tools, and expands the selected full contract, and firecrawl_scrape with alexandria: [{provider, capability, options}] executes up to ten capabilities and returns their results. Alexandria access needs an API key on a team with it enabled. Provide only the required inputs and account for stated network or external side effects.`;
3896
3904
  var KEYLESS_PROFILE_INSTRUCTIONS = `Hosted keyless sessions expose firecrawl_search, firecrawl_scrape, and firecrawl_parse with usage limits. firecrawl_search searches the web. For programming questions, firecrawl_search with categories: ["developer"] searches indexed public repositories, GitHub issues, merged pull requests, repository READMEs, and code documentation. For legal or regulatory questions, firecrawl_search with categories: ["gov"] searches US government legal and regulatory sources and cannot be combined with other categories. For biomedical, life-science, clinical, or arXiv literature, firecrawl_search with categories: ["research"] filters ordinary web results to research-affiliated websites. firecrawl_scrape retrieves one supplied page and can return JSON matching a supplied schema. firecrawl_parse processes supported local files through its two-phase upload flow. An Authorization bearer API key can provide higher usage limits and expose additional tools, subject to plan, deployment, and team policy, including firecrawl_map for site URL discovery, firecrawl_agent and firecrawl_agent_status for multi-source research that returns structured data when the URLs are not known, firecrawl_research_* for paper-index and repository research, and firecrawl_find_tools as the progressive Alexandria catalogue lookup alongside the Alexandria options of firecrawl_search and firecrawl_scrape for catalogued data providers.`;
3897
3905
  function deprecatedExtractPayload() {
3898
3906
  return {
@@ -4561,7 +4569,7 @@ Scrape one URL and return its content: markdown by default, or HTML, links, scre
4561
4569
 
4562
4570
  Firecrawl may serve recently indexed content; set \`maxAge: 0\` for a live fetch or a smaller \`maxAge\` to bound staleness. A successful response does not by itself confirm the page is still current. ${SAFE_MODE ? "A named browser profile loads saved session data without saving changes to it." : "Browser actions can change the live page when interactive actions are enabled."} Authenticated responses can include a \`metadata.scrapeId\` for optional scrape feedback.
4563
4571
 
4564
- On an authenticated session with Alexandria access, \`firecrawl_search\` with \`sources\` unset and \`firecrawl_find_tools\` can discover providers for the same fields across several pages; a matching provider returns typed records in one call. Keyless sessions have no provider matches.
4572
+ On an authenticated session with Alexandria access, \`firecrawl_search\` and \`firecrawl_find_tools\` can discover providers for the same fields across several pages; a matching provider returns typed records in one call. Keyless sessions have no provider matches.
4565
4573
 
4566
4574
  Alexandria mode, on an authenticated session with Alexandria access: \`alexandria\` selects catalogued capability execution and is mutually exclusive with \`url\`.
4567
4575
  `,
@@ -4691,11 +4699,13 @@ For a programming question, add \`categories: ["developer"]\`; its hits return i
4691
4699
  ),
4692
4700
  execute: async (args2, { session, log, client: mcpClient }) => {
4693
4701
  const { query, ...opts } = args2;
4702
+ const requestedSources = normalizeSearchSources(
4703
+ Array.isArray(opts.sources) && opts.sources.length ? opts.sources : ["web"]
4704
+ );
4705
+ const addsAlexandria = hasCredential(session) && enterpriseAllowsAlexandria(opts.enterprise) && !hasAlexandria(requestedSources);
4694
4706
  const searchOpts = {
4695
4707
  ...opts,
4696
- sources: normalizeSearchSources(
4697
- opts.sources ?? (hasCredential(session) ? ["web", "alexandria"] : ["web"])
4698
- )
4708
+ sources: addsAlexandria ? withAlexandriaSource(requestedSources) : requestedSources
4699
4709
  };
4700
4710
  searchOpts.domainTools ??= defaultDomainTools(searchOpts.sources);
4701
4711
  searchOpts.toolDetail ??= "compact";
@@ -4725,7 +4735,8 @@ For a programming question, add \`categories: ["developer"]\`; its hits return i
4725
4735
  const postSearch = () => postSearchWithFallback(
4726
4736
  client,
4727
4737
  searchBody,
4728
- opts.sources === void 0 && opts.domainTools !== true
4738
+ addsAlexandria && opts.domainTools !== true,
4739
+ requestedSources
4729
4740
  );
4730
4741
  const httpRes = await relayExchangeError(postSearch, { tool: "firecrawl_search" });
4731
4742
  return structuredCompact(withoutDiscoveredToolPrices(httpRes?.data ?? {}));
@@ -6384,7 +6395,7 @@ function searchSurfaceScrapeDescription(safeMode) {
6384
6395
  return `
6385
6396
  Scrape one URL and return its content, or execute catalogued Alexandria capabilities. URL mode returns markdown by default, or HTML, links, screenshots, branding data, a targeted answer, or JSON matching a supplied schema, plus page metadata. Firecrawl may serve recently indexed content; set \`maxAge: 0\` for a live fetch. A successful response does not by itself confirm the page is still current. ${safeMode ? "A named browser profile loads saved session data without saving changes to it." : "Browser actions can change the live page, and a named browser profile can load saved session data and overwrite its stored state."}
6386
6397
 
6387
- \`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.
6398
+ \`firecrawl_search\` and \`firecrawl_find_tools\` can discover providers for the same fields across several pages; a matching Alexandria provider returns typed records in one call.
6388
6399
 
6389
6400
  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.
6390
6401
  `;
@@ -6440,6 +6451,11 @@ Returns result groups in \`data\` and an operation \`id\`.
6440
6451
  toolDetail
6441
6452
  } = args2;
6442
6453
  const searchQuery = query ?? "";
6454
+ const requestedSources = normalizeSearchSources(
6455
+ sources?.length ? sources : ["web"]
6456
+ );
6457
+ const addsAlexandria = hasCredential(session) && enterpriseAllowsAlexandria(enterprise) && !hasAlexandria(requestedSources);
6458
+ const searchSources = addsAlexandria ? withAlexandriaSource(requestedSources) : requestedSources;
6443
6459
  const searchBody = {
6444
6460
  query: searchQuery,
6445
6461
  ...removeEmptyTopLevel({
@@ -6449,12 +6465,12 @@ Returns result groups in \`data\` and an operation \`id\`.
6449
6465
  tbs,
6450
6466
  filter,
6451
6467
  location,
6452
- sources: normalizeSearchSources(sources ?? ["web", "alexandria"]),
6468
+ sources: searchSources,
6453
6469
  categories,
6454
6470
  highlights,
6455
6471
  enterprise,
6456
6472
  toolDetail: toolDetail ?? "compact",
6457
- domainTools: domainTools ?? defaultDomainTools(sources ?? ["web", "alexandria"])
6473
+ domainTools: domainTools ?? defaultDomainTools(searchSources)
6458
6474
  }),
6459
6475
  origin: requestOrigin(mcpClient, session)
6460
6476
  };
@@ -6466,7 +6482,8 @@ Returns result groups in \`data\` and an operation \`id\`.
6466
6482
  const postSearch = () => postSearchWithFallback(
6467
6483
  client,
6468
6484
  searchBody,
6469
- sources === void 0 && domainTools !== true
6485
+ addsAlexandria && domainTools !== true,
6486
+ requestedSources
6470
6487
  );
6471
6488
  const httpRes = await relayExchangeError(postSearch, { tool: "firecrawl_search" });
6472
6489
  return structuredCompactResult(httpRes?.data ?? {});
package/dist/server.d.ts CHANGED
@@ -44,6 +44,10 @@ declare function keylessQuotaReason(reason: unknown): reason is 'requests' | 'cr
44
44
 
45
45
  declare function hasAlexandria(sources: unknown): boolean;
46
46
  declare function defaultDomainTools(sources: unknown): boolean;
47
+ /** Adds alexandria to the requested sources, keeping the caller's entries and their string or object form. */
48
+ declare function withAlexandriaSource(sources: unknown): unknown[];
49
+ /** Zero data retention and anonymous searches cannot run provider discovery. */
50
+ declare function enterpriseAllowsAlexandria(enterprise: unknown): boolean;
47
51
  declare function normalizeSearchSources(sources: unknown): unknown;
48
52
  declare function searchQueryIsValid(args: {
49
53
  query?: string;
@@ -146,7 +150,8 @@ type ExchangeErrorContext = {
146
150
  };
147
151
  declare function relayTermsRequired<T>(run: () => Promise<T>, context: ExchangeErrorContext): Promise<T>;
148
152
  declare function relayExchangeError(run: () => Promise<any>, context: ExchangeErrorContext): Promise<any>;
149
- declare function postSearchWithFallback(client: any, body: Record<string, unknown>, implicitTools: boolean): Promise<any>;
153
+ /** Retries without Alexandria, on fallbackSources, when tools the caller did not ask for are refused. */
154
+ declare function postSearchWithFallback(client: any, body: Record<string, unknown>, implicitTools: boolean, fallbackSources?: unknown[]): Promise<any>;
150
155
 
151
156
  /**
152
157
  * Library entry point: `import { createFirecrawlMcpServer } from 'firecrawl-mcp/server'`.
@@ -423,4 +428,4 @@ declare const structuredCompactResult: (data: unknown) => ToolResult;
423
428
 
424
429
  declare function createFirecrawlMcpServer(options?: FirecrawlMcpServerOptions): FirecrawlMcpServer;
425
430
 
426
- export { ALEXANDRIA_CATALOGUE_VERTICALS, ALEXANDRIA_SEARCH_INSTRUCTIONS, type AuthenticationRequest, type ExtraToolsContext, type FirecrawlMcpServer, type FirecrawlMcpServerHooks, type FirecrawlMcpServerOptions, type FirecrawlMcpServerStartArgs, type HttpApp, type InstructionDefaults, keylessToolNames as KEYLESS_TOOL_NAMES, type OutboundRequest, type ProtectedResourceMetadata, type ResourceContent, type ResourceDefinition, type ResourceRegistrar, SEARCH_DOMAINS_CONFLICT_MESSAGE, type Session, type SessionData, type ToolCallEvent, type ToolContext, type ToolDefinition, type ToolIcon, type ToolLogger, type ToolRegistrar, type ToolResult, UserError, assertExchangeCredential, createFirecrawlMcpServer, defaultDomainTools, hasAlexandria, invalidApiKeyRecoveryPayload, invalidOAuthRecoveryPayload, keylessQuotaReason, keylessSignupUrlFrom, normalizeHeader, normalizeSearchSources, originHeaders, postSearchWithFallback, recoveryPayload, relayExchangeError, relayTermsRequired, removeEmptyTopLevel, requestOrigin, searchDomainsAreExclusive, searchOutputSchema, searchQueryIsValid, searchToolBaseFields, structuredCompactResult as structuredCompact, withoutTrailingSlash };
431
+ export { ALEXANDRIA_CATALOGUE_VERTICALS, ALEXANDRIA_SEARCH_INSTRUCTIONS, type AuthenticationRequest, type ExtraToolsContext, type FirecrawlMcpServer, type FirecrawlMcpServerHooks, type FirecrawlMcpServerOptions, type FirecrawlMcpServerStartArgs, type HttpApp, type InstructionDefaults, keylessToolNames as KEYLESS_TOOL_NAMES, type OutboundRequest, type ProtectedResourceMetadata, type ResourceContent, type ResourceDefinition, type ResourceRegistrar, SEARCH_DOMAINS_CONFLICT_MESSAGE, type Session, type SessionData, type ToolCallEvent, type ToolContext, type ToolDefinition, type ToolIcon, type ToolLogger, type ToolRegistrar, type ToolResult, UserError, assertExchangeCredential, createFirecrawlMcpServer, defaultDomainTools, enterpriseAllowsAlexandria, hasAlexandria, invalidApiKeyRecoveryPayload, invalidOAuthRecoveryPayload, keylessQuotaReason, keylessSignupUrlFrom, normalizeHeader, normalizeSearchSources, originHeaders, postSearchWithFallback, recoveryPayload, relayExchangeError, relayTermsRequired, removeEmptyTopLevel, requestOrigin, searchDomainsAreExclusive, searchOutputSchema, searchQueryIsValid, searchToolBaseFields, structuredCompactResult as structuredCompact, withAlexandriaSource, withoutTrailingSlash };
package/dist/server.js CHANGED
@@ -2396,6 +2396,14 @@ function defaultDomainTools(sources) {
2396
2396
  (source) => ["web", "news", "images"].includes(typeof source === "string" ? source : source?.type)
2397
2397
  );
2398
2398
  }
2399
+ function withAlexandriaSource(sources) {
2400
+ if (!Array.isArray(sources) || sources.length === 0) return ["web", "alexandria"];
2401
+ if (hasAlexandria(sources)) return sources;
2402
+ return [...sources, typeof sources[0] === "string" ? "alexandria" : { type: "alexandria" }];
2403
+ }
2404
+ function enterpriseAllowsAlexandria(enterprise) {
2405
+ return !(Array.isArray(enterprise) && enterprise.some((mode) => mode === "zdr" || mode === "anon"));
2406
+ }
2399
2407
  function normalizeSearchSources(sources) {
2400
2408
  if (!Array.isArray(sources)) return sources;
2401
2409
  return sources.map(
@@ -2422,8 +2430,8 @@ var findToolsSchema = z5.object({
2422
2430
  }).strict();
2423
2431
  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";
2424
2432
  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.";
2425
- var ALEXANDRIA_SOURCES_OPT_OUT = 'A search with sources: ["web"] omits semantic provider discovery; domainTools: true can still return website-matched tools. Web-only results use domainTools: false.';
2426
- var ALEXANDRIA_SEARCH_LEAD = "Authenticated search also returns matching Alexandria data providers in data.tools (" + ALEXANDRIA_CATALOGUE_VERTICALS + "). Prefer a provider over scraping pages when the task needs the same fields across several entities, exact figures or timestamps, provenance, or many records; use web results when they already answer the question. " + ALEXANDRIA_SOURCES_OPT_OUT;
2433
+ var ALEXANDRIA_SOURCES_ALWAYS_ON = 'Authenticated searches always add alexandria to the sources, so sources: ["web"] also returns providers; domainTools: false turns off website-matched tools only.';
2434
+ var ALEXANDRIA_SEARCH_LEAD = "Authenticated search also returns matching Alexandria data providers in data.tools (" + ALEXANDRIA_CATALOGUE_VERTICALS + "). Prefer a provider over scraping pages when the task needs the same fields across several entities, exact figures or timestamps, provenance, or many records; use web results when they already answer the question. " + ALEXANDRIA_SOURCES_ALWAYS_ON;
2427
2435
  var ALEXANDRIA_CONTRACT_GUIDANCE = "The selected contract marks required inputs and any requiresOneOf groups (at least one member per group); it may include example.request/example.response and response.key (which may differ from records). Where pagination is declared, its fields govern paging with the same filters; catalogue next is separate from provider pagination.";
2428
2436
  function findToolsOptions(args) {
2429
2437
  const level = args.level ?? (args.query || args.capabilities?.length || args.providers?.length || args.groups?.length || args.urls?.length ? "tools" : args.categories?.length ? "providers" : "categories");
@@ -2455,7 +2463,7 @@ function withFindToolsNavigation(envelope, carry = {}) {
2455
2463
  if (link(page.next)) page.nextTool = link(page.next);
2456
2464
  return envelope;
2457
2465
  }
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.';
2466
+ var ALEXANDRIA_SEARCH_INSTRUCTIONS = 'Authenticated search combines web results, semantic tool summaries and domain matches. Use sources: ["alexandria"] for semantic tools only. ' + ALEXANDRIA_SOURCES_ALWAYS_ON + ' 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
2467
  var TOOL_PRICE_KEYS = ["creditsCost", "perRecord", "billing", "recordsPerUnit", "zeroDataRetentionCreditsCost"];
2460
2468
  function withoutToolPrice(tool) {
2461
2469
  if (!tool || typeof tool !== "object" || Array.isArray(tool)) return tool;
@@ -3672,7 +3680,7 @@ var searchToolBaseFields = {
3672
3680
  location: z11.string().optional(),
3673
3681
  includeDomains: z11.array(searchDomainSchema).optional().describe("Hostnames to restrict results to. Mutually exclusive with excludeDomains."),
3674
3682
  excludeDomains: z11.array(searchDomainSchema).optional().describe("Hostnames to leave out of results. Mutually exclusive with includeDomains."),
3675
- sources: z11.array(searchSourceSchema).optional().describe("Search sources; authenticated sessions default to web + alexandria, keyless sessions to web only. " + ALEXANDRIA_SOURCES_OPT_OUT + ' Use ["alexandria"] alone for provider discovery without web results.'),
3683
+ sources: z11.array(searchSourceSchema).optional().describe("Search sources; authenticated sessions default to web + alexandria, keyless sessions to web only. " + ALEXANDRIA_SOURCES_ALWAYS_ON + ' enterprise zdr or anon searches do not add it. Use ["alexandria"] alone for provider discovery without web results.'),
3676
3684
  categories: z11.array(z11.enum(["research", "pdf", "developer", "gov"])).optional().describe(
3677
3685
  "Limit results to specific source types. `research` restricts ordinary web results to research-affiliated websites and returns page snippets, which is separate from the `firecrawl_research_*` tools that search paper abstracts and full text across biomedical (PubMed, bioRxiv, medRxiv) and arXiv literature; `pdf` searches PDF results; `developer` searches an index built for coding agents over public repositories, GitHub issues, merged pull requests, repository READMEs, and code documentation; `gov` searches the Government Index of US federal, state, and local legal and regulatory sources, the index behind firecrawl_gov_search, and cannot be combined with other categories; gov hits can include historical versions, bill text, agency guidance, and third-party reproductions, so verify the issuer, jurisdiction, enacted/effective status, and version before citing current governing law, clarify a missing jurisdiction or ambiguous as-of date, and use general search for non-US questions or missing coverage (no hits does not establish that no applicable law exists). `developer` and `gov` return hits in `data.web` with `category` set to their name; the other categories also filter `data.web`."
3678
3686
  ),
@@ -3814,7 +3822,7 @@ async function relayExchangeError(run, context) {
3814
3822
  });
3815
3823
  }
3816
3824
  }
3817
- async function postSearchWithFallback(client, body, implicitTools) {
3825
+ async function postSearchWithFallback(client, body, implicitTools, fallbackSources = ["web"]) {
3818
3826
  try {
3819
3827
  return await client.http.post("/v2/search", body);
3820
3828
  } catch (error2) {
@@ -3827,7 +3835,7 @@ async function postSearchWithFallback(client, body, implicitTools) {
3827
3835
  if (!implicitTools || response?.status !== 403 || !unavailable) throw error2;
3828
3836
  return client.http.post("/v2/search", {
3829
3837
  ...body,
3830
- sources: ["web"],
3838
+ sources: fallbackSources,
3831
3839
  domainTools: false
3832
3840
  });
3833
3841
  }
@@ -3887,7 +3895,7 @@ var ConsoleLogger = class {
3887
3895
  }
3888
3896
  }
3889
3897
  };
3890
- var FULL_PROFILE_INSTRUCTIONS = `Firecrawl provides web search, page retrieval, site URL discovery, multi-page collection, structured page data, monitoring, and multi-source research that returns structured data. Match the requested operation to the tool boundary: firecrawl_scrape retrieves one supplied page and can return JSON matching a supplied schema, firecrawl_map enumerates URLs under a site without retrieving their content, and firecrawl_agent runs multi-source research and returns structured data when the URLs are not known or the answer spans several sites (an entity plus its fields, a list, a dataset); its result is read with firecrawl_agent_status. Authenticated firecrawl_search returns web results together with matching Alexandria providers in data.tools. ${ALEXANDRIA_CATALOGUE_SENTENCE} A matching provider can return the same fields across several entities, provenance, exact figures or timestamps, or a large set of records through firecrawl_scrape with its published contract. If web results already answer the question, use them. For the same fields across multiple pages, firecrawl_find_tools offers free provider discovery. Use firecrawl_find_tools to read a contract that was not returned in full or to browse the catalogue by category. ${ALEXANDRIA_SOURCES_OPT_OUT} If no provider fits, continue with web search or firecrawl_agent. For biomedical, life-science, clinical, or arXiv literature, the firecrawl_research_* tools search a paper index of abstracts and full text; firecrawl_search with categories: ["research"] is a website filter over ordinary web results and reaches different sources. For a programming question (code behaviour, a library or framework, an API contract, an error message, or a known bug), firecrawl_developer_search (or firecrawl_search with categories: ["developer"]) searches an index of public repositories, GitHub issues, merged pull requests, READMEs, and code documentation. 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 and cannot be combined with other categories. firecrawl_search with sources: [{type: "alexandria"}] returns compact tool summaries in data.tools; toolDetail: "full" includes contracts, firecrawl_find_tools starts with categories, lists providers, then compact tools, and expands the selected full contract, and firecrawl_scrape with alexandria: [{provider, capability, options}] executes up to ten capabilities and returns their results. Alexandria access needs an API key on a team with it enabled. Provide only the required inputs and account for stated network or external side effects.`;
3898
+ var FULL_PROFILE_INSTRUCTIONS = `Firecrawl provides web search, page retrieval, site URL discovery, multi-page collection, structured page data, monitoring, and multi-source research that returns structured data. Match the requested operation to the tool boundary: firecrawl_scrape retrieves one supplied page and can return JSON matching a supplied schema, firecrawl_map enumerates URLs under a site without retrieving their content, and firecrawl_agent runs multi-source research and returns structured data when the URLs are not known or the answer spans several sites (an entity plus its fields, a list, a dataset); its result is read with firecrawl_agent_status. Authenticated firecrawl_search returns web results together with matching Alexandria providers in data.tools. ${ALEXANDRIA_CATALOGUE_SENTENCE} A matching provider can return the same fields across several entities, provenance, exact figures or timestamps, or a large set of records through firecrawl_scrape with its published contract. If web results already answer the question, use them. For the same fields across multiple pages, firecrawl_find_tools offers free provider discovery. Use firecrawl_find_tools to read a contract that was not returned in full or to browse the catalogue by category. ${ALEXANDRIA_SOURCES_ALWAYS_ON} If no provider fits, continue with web search or firecrawl_agent. For biomedical, life-science, clinical, or arXiv literature, the firecrawl_research_* tools search a paper index of abstracts and full text; firecrawl_search with categories: ["research"] is a website filter over ordinary web results and reaches different sources. For a programming question (code behaviour, a library or framework, an API contract, an error message, or a known bug), firecrawl_developer_search (or firecrawl_search with categories: ["developer"]) searches an index of public repositories, GitHub issues, merged pull requests, READMEs, and code documentation. 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 and cannot be combined with other categories. firecrawl_search with sources: [{type: "alexandria"}] returns compact tool summaries in data.tools; toolDetail: "full" includes contracts, firecrawl_find_tools starts with categories, lists providers, then compact tools, and expands the selected full contract, and firecrawl_scrape with alexandria: [{provider, capability, options}] executes up to ten capabilities and returns their results. Alexandria access needs an API key on a team with it enabled. Provide only the required inputs and account for stated network or external side effects.`;
3891
3899
  var KEYLESS_PROFILE_INSTRUCTIONS = `Hosted keyless sessions expose firecrawl_search, firecrawl_scrape, and firecrawl_parse with usage limits. firecrawl_search searches the web. For programming questions, firecrawl_search with categories: ["developer"] searches indexed public repositories, GitHub issues, merged pull requests, repository READMEs, and code documentation. For legal or regulatory questions, firecrawl_search with categories: ["gov"] searches US government legal and regulatory sources and cannot be combined with other categories. For biomedical, life-science, clinical, or arXiv literature, firecrawl_search with categories: ["research"] filters ordinary web results to research-affiliated websites. firecrawl_scrape retrieves one supplied page and can return JSON matching a supplied schema. firecrawl_parse processes supported local files through its two-phase upload flow. An Authorization bearer API key can provide higher usage limits and expose additional tools, subject to plan, deployment, and team policy, including firecrawl_map for site URL discovery, firecrawl_agent and firecrawl_agent_status for multi-source research that returns structured data when the URLs are not known, firecrawl_research_* for paper-index and repository research, and firecrawl_find_tools as the progressive Alexandria catalogue lookup alongside the Alexandria options of firecrawl_search and firecrawl_scrape for catalogued data providers.`;
3892
3900
  function deprecatedExtractPayload() {
3893
3901
  return {
@@ -4556,7 +4564,7 @@ Scrape one URL and return its content: markdown by default, or HTML, links, scre
4556
4564
 
4557
4565
  Firecrawl may serve recently indexed content; set \`maxAge: 0\` for a live fetch or a smaller \`maxAge\` to bound staleness. A successful response does not by itself confirm the page is still current. ${SAFE_MODE ? "A named browser profile loads saved session data without saving changes to it." : "Browser actions can change the live page when interactive actions are enabled."} Authenticated responses can include a \`metadata.scrapeId\` for optional scrape feedback.
4558
4566
 
4559
- On an authenticated session with Alexandria access, \`firecrawl_search\` with \`sources\` unset and \`firecrawl_find_tools\` can discover providers for the same fields across several pages; a matching provider returns typed records in one call. Keyless sessions have no provider matches.
4567
+ On an authenticated session with Alexandria access, \`firecrawl_search\` and \`firecrawl_find_tools\` can discover providers for the same fields across several pages; a matching provider returns typed records in one call. Keyless sessions have no provider matches.
4560
4568
 
4561
4569
  Alexandria mode, on an authenticated session with Alexandria access: \`alexandria\` selects catalogued capability execution and is mutually exclusive with \`url\`.
4562
4570
  `,
@@ -4686,11 +4694,13 @@ For a programming question, add \`categories: ["developer"]\`; its hits return i
4686
4694
  ),
4687
4695
  execute: async (args, { session, log, client: mcpClient }) => {
4688
4696
  const { query, ...opts } = args;
4697
+ const requestedSources = normalizeSearchSources(
4698
+ Array.isArray(opts.sources) && opts.sources.length ? opts.sources : ["web"]
4699
+ );
4700
+ const addsAlexandria = hasCredential(session) && enterpriseAllowsAlexandria(opts.enterprise) && !hasAlexandria(requestedSources);
4689
4701
  const searchOpts = {
4690
4702
  ...opts,
4691
- sources: normalizeSearchSources(
4692
- opts.sources ?? (hasCredential(session) ? ["web", "alexandria"] : ["web"])
4693
- )
4703
+ sources: addsAlexandria ? withAlexandriaSource(requestedSources) : requestedSources
4694
4704
  };
4695
4705
  searchOpts.domainTools ??= defaultDomainTools(searchOpts.sources);
4696
4706
  searchOpts.toolDetail ??= "compact";
@@ -4720,7 +4730,8 @@ For a programming question, add \`categories: ["developer"]\`; its hits return i
4720
4730
  const postSearch = () => postSearchWithFallback(
4721
4731
  client,
4722
4732
  searchBody,
4723
- opts.sources === void 0 && opts.domainTools !== true
4733
+ addsAlexandria && opts.domainTools !== true,
4734
+ requestedSources
4724
4735
  );
4725
4736
  const httpRes = await relayExchangeError(postSearch, { tool: "firecrawl_search" });
4726
4737
  return structuredCompact(withoutDiscoveredToolPrices(httpRes?.data ?? {}));
@@ -5729,6 +5740,7 @@ export {
5729
5740
  assertExchangeCredential,
5730
5741
  createFirecrawlMcpServer,
5731
5742
  defaultDomainTools,
5743
+ enterpriseAllowsAlexandria,
5732
5744
  hasAlexandria,
5733
5745
  invalidApiKeyRecoveryPayload,
5734
5746
  invalidOAuthRecoveryPayload,
@@ -5748,5 +5760,6 @@ export {
5748
5760
  searchQueryIsValid,
5749
5761
  searchToolBaseFields,
5750
5762
  structuredCompactResult as structuredCompact,
5763
+ withAlexandriaSource,
5751
5764
  withoutTrailingSlash
5752
5765
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "firecrawl-mcp",
3
- "version": "3.30.2",
3
+ "version": "3.30.3",
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",