From eee449e3691cd0be228bed5bc712d0eef6135b36 Mon Sep 17 00:00:00 2001 From: Developers Digest <124798203+developersdigest@users.noreply.github.com> Date: Tue, 15 Sep 2026 14:35:45 -0400 Subject: [PATCH 1/2] Improve natural Alexandria discovery and retain Find Tools command --- beta-skills/firecrawl-alexandria/SKILL.md | 85 +++++---- skills/firecrawl-search/SKILL.md | 12 +- src/__tests__/alexandria-beta.test.ts | 205 +++++++++++++++++++++- src/commands/alexandria.ts | 50 ++++-- src/commands/search.ts | 30 +++- src/index.ts | 15 +- src/types/search.ts | 2 +- 7 files changed, 326 insertions(+), 73 deletions(-) diff --git a/beta-skills/firecrawl-alexandria/SKILL.md b/beta-skills/firecrawl-alexandria/SKILL.md index 7b30202faf..134311cedf 100644 --- a/beta-skills/firecrawl-alexandria/SKILL.md +++ b/beta-skills/firecrawl-alexandria/SKILL.md @@ -1,6 +1,6 @@ --- name: firecrawl-alexandria -description: Use for explicitly requested Firecrawl Alexandria beta tool discovery or provider execution, including Find Tools, provider-backed search, and structured third-party data. Requires an authorized Firecrawl API key; does not replace normal web search or scraping. +description: Use with Firecrawl beta search when natural web results include Alexandria tools, when the user explicitly wants tools for a task or website, or when executing a discovered provider tool. Search normally, inspect matching contracts, and execute through Scrape. Find Tools is the catalogue meta tool. Requires an authorized Firecrawl API key. --- # Alexandria Beta @@ -9,77 +9,84 @@ Use the beta CLI explicitly on every invocation: `npx firecrawl-cli@alexandria`. Use `FIRECRAWL_API_KEY` or existing Firecrawl login credentials. Never print credentials. Installing the beta is not authorization: the API enforces team and provider access. -## Discover Before Executing +## Natural search first -Default to search with domain-tool discovery enabled. In this beta, plain `search` sends both `web` and `alexandria` sources with `domainTools: true`. Use `--domain-tools` explicitly in agent examples so this remains clear, including when selecting only web results. - -### Semantic search with domain discovery - -Start with a capability query and keep domain-tool discovery enabled. Default search combines semantic Alexandria tool matches with web results and tools for those result domains: +Start with the user's actual question, including the location, marketplace, and constraints. Do not rewrite an ordinary research question into a request for APIs or tools. Default search returns web results and relevant Alexandria tools together, with domain matching enabled: ```sh -npx firecrawl-cli@alexandria search "Search homes for sale and retrieve property price history" --domain-tools --json +npx firecrawl-cli@alexandria search "homes for sale in Lower Haight San Francisco" --json -o .firecrawl/homes.json ``` -If the user names a website, include that context in the same discovery workflow and look up its URL directly when you need its tool contracts: +Read both `data.web` and `data.tools`. Tools are discovery results, not fetched provider data. Use useful web results directly; when a returned tool fits, inspect its contract and execute it through `scrape --alexandria`. Search never automatically executes provider tools, including with `--scrape` (which fetches web page content). -```sh -npx firecrawl-cli@alexandria search "Zillow homes for sale and property price history" --domain-tools --json -npx firecrawl-cli@alexandria find-tools https://www.zillow.com --pretty -``` +A complete contract returned by search needs no additional discovery call. Check country/marketplace, rental versus sale, individual-record versus aggregate coverage, required inputs, `creditsCost`, `perRecord`, and access requirements. Use returned lookup tools to resolve record IDs; never invent them. A related domain or topic does not establish coverage. If no candidate fits, use web results or ordinary URL scrape instead of walking the entire catalogue. -The domain in the query provides context; it is not a strict provider filter. `--domain-tools` discovers tools for domains in the web results. Use `find-tools` with the known URL to inspect that domain even if it does not appear in those results. Inspect the returned matches before making another discovery call; skip the URL lookup when search already returned the needed contract. +`--sources web` opts out of Alexandria. `--sources web --domain-tools` includes tools for web-result domains. `--no-domain-tools` disables domain matching but does not remove semantic Alexandria results when that source is selected. Keep the normal default unless the user requests a narrower source. -Describe the data capability in the discovery query; keep exact street addresses, record IDs, and other execution arguments for the selected tool. For example, discover "residential property prices near an address", then resolve the user's address using the returned lookup contract. Do not claim rental support if the contract only supports for-sale listings. +## Explicit requests for tools: search then the Find Tools meta tool -When only semantic tool matches are needed, narrow the same search to the Alexandria source: +For “find tools that can look up company filings,” search only tool capabilities: ```sh -npx firecrawl-cli@alexandria search "Search homes for sale and retrieve property price history" --sources alexandria --json +npx firecrawl-cli@alexandria search "tools to search company filings" --sources alexandria --json ``` -If selecting only web results, use `--sources web --domain-tools` to retain domain discovery; `--sources web` alone opts out. `find-tools` accepts URLs and catalogue selectors, not a natural-language search phrase. Both semantic and domain discovery return tool information without executing provider tools. Read the returned providers and capabilities rather than guessing a provider from a keyword. +Then use `find-tools` when the user wants a set of tools for a returned provider, a known website, or a specific contract. It is a meta tool: it lists tools and their inputs, without executing them. The CLI sends `firecrawl/find-tools` through the same Scrape API used for every provider execution. Do not call Exchange endpoints directly. -### Progressive catalogue discovery +```sh +# Known website: discover its providers, without fetching the URL +npx firecrawl-cli@alexandria find-tools https://www.zillow.com --json -When the provider is unknown or a result exposes more groups/tools, narrow the catalogue progressively instead of loading every contract: +# After discovery identifies zillow: list its tools, compactly +npx firecrawl-cli@alexandria find-tools --options '{"providers":["zillow"],"level":"tools","limit":100}' --json -```sh -npx firecrawl-cli@alexandria find-tools --options '{"level":"providers"}' --json +# Inspect only the selected contract +npx firecrawl-cli@alexandria find-tools --options '{"providers":["zillow"],"capabilities":["properties/locations"],"level":"tools","expand":["options","response"]}' --json ``` -Inspect the compact results and follow the relevant returned `next` request with `find-tools --request ''`. Pass the complete request object unchanged, including its provider, capability, and options. Continue through the relevant provider, group, and tool results; use returned pagination requests when needed. Do not combine `--request` with URL or filter arguments. +`find-tools` accepts URLs and catalogue selectors, not a free-text query. Use Alexandria-only search for natural-language tool intent. Valid catalogue selectors: `urls`, `providers`, `categories`, `groups`, `capabilities`. Valid `level` values: `providers`, `groups`, `tools` (not `capabilities`). `limit` accepts 1–100 and defaults to 5; use 100 for an explicitly requested broad tool list. Follow pagination only if more results are needed. Add `examples` to `expand` only when inputs remain unclear. + +Items are at `data.alexandria[i].data.items`; each call has its own envelope. A returned `next` is a complete request for the same meta tool: -Once a capability fits the task, request only its contract with `--options`, including the returned provider/capability IDs, `"level":"tools"`, and `"expand":["options","response"]`. Add `"examples"` only if the schema needs clarification. Progressive discovery is catalogue navigation, not semantic search or provider execution; use `search --sources alexandria` when starting from a natural-language capability. +```sh +npx firecrawl-cli@alexandria find-tools --request '' --json +``` -### Optional tool discovery alongside a scrape +Pass that request unchanged; do not combine `--request` with URL/filter arguments. The equivalent explicit meta-tool execution is: ```sh -npx firecrawl-cli@alexandria scrape https://www.zillow.com --domain-tools --json +npx firecrawl-cli@alexandria scrape --alexandria firecrawl/find-tools --options '{"providers":["zillow"],"level":"tools","limit":100}' --json ``` -Enable `--domain-tools` when a URL scrape should also return related tool contracts and the team has access. If the API refuses the feature, report the access requirement; do not repeatedly retry. A normal URL scrape does not enable this automatically. Inspect the complete JSON for both scraped content and tool metadata; discovering a tool does not execute it. Search and URL scraping can consume credits. +An empty URL lookup means no visible provider matched that domain. A semantic match can still target a different country or unsupported segment. Never make an unrelated paid probe to test coverage. -Read returned tool contracts and any tool metadata before choosing a provider/capability; search and URL-scrape responses expose these as `data.tools`, while `find-tools` responses are under `data.alexandria`. Use their exact input schema, pricing and access requirements; never invent options or assume a provider is free. Follow returned Find Tools requests with `find-tools --request ''`. This accepts only the `firecrawl/find-tools` discovery call, not arbitrary provider execution. +## Execute through Scrape -## Search → Inspect → Scrape +After inspecting a fitting contract, run it through the normal scrape command: -Use semantic search with domain discovery as the shared entry point, incorporating any known website as described above. Continue with progressive discovery when the returned catalogue needs narrowing, then inspect and execute the selected tool. +```sh +npx firecrawl-cli@alexandria scrape --alexandria zillow/properties/locations --options '{"query":"800 Haight Street San Francisco","count":3}' --json +``` -1. Search once and inspect the returned tool identities and descriptions. A related topic alone does not mean the tool can answer the question. -2. Fetch only the selected provider's or capability's contract with `find-tools`. Omit `expand` for compact results; request `"expand":["options","response"]` only for the selected capability. Load examples only when needed. -3. Check coverage, required inputs, credits, and terms. Use the provider's lookup tool to obtain IDs; never invent an ASIN, zpid, store ID, or opportunity ID. -4. Execute the chosen tool through `scrape --alexandria`, using the exact capability and options returned by discovery. Check per-call errors and receipts before describing the result as successful. -5. If no tool covers the task, stop catalogue execution and use ordinary web search or URL scraping. Do not make a paid call merely to see whether an unrelated tool might work. +This resolves an address; it does not itself return nearby rental prices. Continue only with supported capabilities and returned identifiers. -For example, after discovery confirms Zillow's address lookup contract: +For an existing URL, ordinary scrape can optionally return related tools alongside the page: ```sh -npx firecrawl-cli@alexandria find-tools --options '{"providers":["zillow"],"capabilities":["properties/locations"],"level":"tools","expand":["options","response"]}' --json -npx firecrawl-cli@alexandria scrape --alexandria zillow/properties/locations --options '{"query":"800 Haight Street San Francisco","count":3}' --json +npx firecrawl-cli@alexandria scrape https://www.zillow.com --domain-tools --json ``` -This resolves an address; it does not itself return nearby rental prices. Continue only with supported capabilities and identifiers actually returned by the tool. If a prerequisite lookup is unavailable, explain the missing input instead of guessing it. +This discovers tools without executing them. On access refusal, report it rather than repeatedly retrying or bypassing the gate. + +## Read receipts and failures + +- Search: `creditsUsed` and `id` at the top level. +- URL scrape: `metadata.creditsUsed` in its JSON output. +- Meta-tool/provider calls: `data.creditsCost` plus `data.alexandria[i].creditsCost`; inspect each call's `error` too. +- Tool prices are `creditsCost` and `perRecord`, not a `pricing` field. Do not assume every tool has the same price. +- Save JSON and stderr separately. `2>&1` mixes Request ID lines into JSON and breaks parsing. +- Team balance deltas include concurrent users and tests. Attribute spend from receipts, and reconcile the full time window before alleging overbilling. +- Empty provider results may still be billed. A successful HTTP envelope is not proof the task returned usable records. ## Execute Within The User's Budget diff --git a/skills/firecrawl-search/SKILL.md b/skills/firecrawl-search/SKILL.md index c3b4334878..7831635fac 100644 --- a/skills/firecrawl-search/SKILL.md +++ b/skills/firecrawl-search/SKILL.md @@ -9,7 +9,7 @@ allowed-tools: # firecrawl search -Web search with optional content scraping. Returns search results as JSON, optionally with full page content. +Search naturally using the user’s actual question. In the Alexandria beta, default search returns web results plus relevant Alexandria tools, with optional web content scraping. ## Quick start @@ -30,6 +30,16 @@ Run `firecrawl search --help` for the full option list. **Done when:** results are saved under `.firecrawl/`, verified non-empty, processed for the request, and one feedback event is sent within the time window (unless opted out). +## Alexandria in normal search + +The beta defaults to `web,alexandria` with domain-tool matching on. Preserve the user's location, marketplace, and constraints in the query; do not turn normal research into an artificial tool-discovery query. Inspect `data.web` and `data.tools` from the same response. + +A tool match is not executed data. If it fits the task, read its inputs, coverage, `creditsCost`/`perRecord`, and access requirements in the JSON. Execute it with `firecrawl scrape --alexandria --options ''`. All provider execution goes through Scrape; `search --scrape` only fetches web result content, not provider tools. + +Use `find-tools` only for an explicitly requested tool set or a missing contract. It runs the `firecrawl/find-tools` meta tool through Scrape and never executes the tools it discovers. It accepts URLs or catalogue selectors; for “tools that can do X,” first use `search "X" --sources alexandria`, then narrow the returned providers with `find-tools --options '{"providers":[""],"level":"tools","limit":100}'`. + +If no returned tool covers the country/market/segment or required inputs, continue with ordinary web results. Do not exhaust the catalogue or pay for adjacent tools just to probe coverage. `--sources web` explicitly opts out of Alexandria; `--sources web --domain-tools` retains domain matches only. + ## Tips - **`--highlights` on by default:** results are query-relevant excerpts, not full-page snippets. Use `--no-highlights` for the original snippets. diff --git a/src/__tests__/alexandria-beta.test.ts b/src/__tests__/alexandria-beta.test.ts index caa21c480c..c9d136fb93 100644 --- a/src/__tests__/alexandria-beta.test.ts +++ b/src/__tests__/alexandria-beta.test.ts @@ -71,14 +71,16 @@ async function cli(args: string[], key = 'fc-test') { } } -it('keeps beta options out of normal help and respects explicit web-only search', async () => { - for (const args of [['--help'], ['search', '--help'], ['scrape', '--help']]) { - const result = await cli(args); - expect(result.code).toBe(0); - expect(result.stdout).not.toMatch( - /alexandria|find-tools|domain-tools|--enable/i - ); - } +it('documents the default discovery flow and respects explicit web-only search', async () => { + const help = await cli(['--help']); + expect(help.stdout).toContain('find-tools'); + const searchHelp = await cli(['search', '--help']); + expect(searchHelp.stdout).toContain('web,alexandria'); + expect(searchHelp.stdout).toContain('--no-domain-tools'); + const scrapeHelp = await cli(['scrape', '--help']); + expect(scrapeHelp.stdout).toContain('--alexandria'); + const findHelp = await cli(['find-tools', '--help']); + expect(findHelp.stdout).toContain('meta tool'); response = { success: true, data: { web: [] } }; const result = await cli([ 'search', @@ -116,7 +118,7 @@ it('preserves mixed search results, tools and billing metadata', async () => { }, }); const readable = await cli(['search', 'pizza hut']); - expect(readable.stdout).toContain('=== Tools ==='); + expect(readable.stdout).toContain('=== Alexandria Tools ==='); expect(readable.stdout).toContain('series/observations'); }); @@ -245,3 +247,188 @@ it('keeps URL scrape tool contracts in the output', async () => { body: { url: 'https://example.com', domainTools: true }, }); }); + +it('keeps natural query text and disables only domain matching when requested', async () => { + response = { success: true, data: { web: [], tools: [] } }; + const query = 'homes for sale in Lower Haight under $1 million'; + const result = await cli(['search', query, '--no-domain-tools', '--json']); + expect(result.code).toBe(0); + expect(requests).toHaveLength(1); + expect(requests[0]).toMatchObject({ + url: '/v2/search', + body: { + query, + domainTools: false, + sources: [{ type: 'web' }, { type: 'alexandria' }], + }, + }); +}); + +it('presents tools compactly after web results while JSON preserves full contracts', async () => { + const tool = { + provider: 'fred', + capability: 'series/observations', + name: 'Economic observations', + description: 'Read an economic series', + creditsCost: 5, + perRecord: true, + options: [{ name: 'series_id', required: true }], + example: { large: 'EXAMPLE_PAYLOAD' }, + }; + response = { + success: true, + data: { + web: [{ url: 'https://example.com', title: 'GDP report' }], + tools: [tool], + }, + }; + const readable = await cli(['search', 'GDP growth']); + expect(readable.stdout.indexOf('GDP report')).toBeLessThan( + readable.stdout.indexOf('=== Alexandria Tools ===') + ); + expect(readable.stdout).toContain('5 credits per record'); + expect(readable.stdout).toContain('scrape --alexandria'); + expect(readable.stdout).not.toContain('EXAMPLE_PAYLOAD'); + const json = await cli(['search', 'GDP growth', '--json']); + expect(JSON.parse(json.stdout).data.tools).toEqual([tool]); + expect(requests.every((request) => request.url === '/v2/search')).toBe(true); +}); + +it('find-tools and explicit meta-tool execution use the same Scrape request', async () => { + const options = '{"providers":["fred"],"level":"tools","limit":100}'; + expect( + (await cli(['find-tools', '--options', options, '--request-id', 'meta-1'])) + .code + ).toBe(0); + expect( + ( + await cli([ + 'scrape', + '--alexandria', + 'firecrawl/find-tools', + '--options', + options, + '--request-id', + 'meta-1', + ]) + ).code + ).toBe(0); + expect(requests).toHaveLength(2); + expect(requests[0]).toEqual(requests[1]); + expect(requests[0].url).toBe('/v2/scrape'); +}); + +it('discovers a known URL and follows its returned meta-tool request without executing providers', async () => { + const next = { + provider: 'firecrawl', + capability: 'find-tools', + options: { providers: ['fred'], level: 'tools', limit: 100 }, + }; + response.data.alexandria = [ + { + provider: 'firecrawl', + capability: 'find-tools', + creditsCost: 0, + data: { items: [{ provider: 'fred', next }], next: null }, + }, + ]; + const first = await cli([ + 'find-tools', + 'https://fred.stlouisfed.org', + '--json', + ]); + expect(first.code).toBe(0); + const returned = JSON.parse(first.stdout).data.alexandria[0].data.items[0] + .next; + expect( + (await cli(['find-tools', '--request', JSON.stringify(returned), '--json'])) + .code + ).toBe(0); + expect(requests[0].body.alexandria[0].options).toEqual({ + urls: ['https://fred.stlouisfed.org'], + }); + expect(requests[1].body.alexandria).toEqual([next]); + expect(requests.every((request) => request.url === '/v2/scrape')).toBe(true); +}); + +it('rejects provider execution and mixed arguments through the find-tools shortcut', async () => { + for (const args of [ + [ + '--request', + '{"provider":"fred","capability":"series/observations","options":{}}', + ], + [ + 'https://example.com', + '--request', + '{"provider":"firecrawl","capability":"find-tools","options":{}}', + ], + [ + '--options', + '{}', + '--request', + '{"provider":"firecrawl","capability":"find-tools","options":{}}', + ], + ]) { + expect((await cli(['find-tools', ...args])).code).toBe(1); + } + expect(requests).toHaveLength(0); +}); + +it('retains empty discovery results and reports nested meta-tool errors as failures', async () => { + response.data = { + alexandria: [ + { + provider: 'firecrawl', + capability: 'find-tools', + creditsCost: 0, + data: { items: [], total: 0, next: null }, + }, + ], + creditsCost: 0, + }; + const empty = await cli(['find-tools', 'https://example.com', '--json']); + expect(empty.code).toBe(0); + expect(JSON.parse(empty.stdout).data.alexandria[0].data).toEqual({ + items: [], + total: 0, + next: null, + }); + response.data.alexandria = [ + { + provider: 'firecrawl', + capability: 'find-tools', + error: { + code: 'invalid_option', + message: 'Unknown discovery level.', + status: 400, + }, + }, + ]; + const invalid = await cli([ + 'find-tools', + '--options', + '{"level":"capabilities"}', + '--json', + ]); + expect(invalid.code).toBe(1); + expect(JSON.parse(invalid.stdout).data.alexandria[0].error.code).toBe( + 'invalid_option' + ); +}); + +it('requests web content with search --scrape without executing returned tools', async () => { + response = { + success: true, + data: { + web: [{ url: 'https://example.com', markdown: 'content' }], + tools: [{ provider: 'fred', capability: 'series/observations' }], + }, + }; + expect((await cli(['search', 'GDP', '--scrape', '--json'])).code).toBe(0); + expect(requests).toHaveLength(1); + expect(requests[0].url).toBe('/v2/search'); + expect(requests[0].body.scrapeOptions.formats).toEqual([ + { type: 'markdown' }, + ]); + expect(requests[0].body.alexandria).toBeUndefined(); +}); diff --git a/src/commands/alexandria.ts b/src/commands/alexandria.ts index 7cb350027c..18f1769842 100644 --- a/src/commands/alexandria.ts +++ b/src/commands/alexandria.ts @@ -124,8 +124,14 @@ export async function handleAlexandria( export function createFindToolsCommand(): Command { return new Command('find-tools') - .argument('[urls...]') - .option('--options ', 'Find Tools catalogue filters') + .description( + 'Discover tool sets and contracts through the firecrawl/find-tools meta tool on Scrape; never executes discovered tools' + ) + .argument('[urls...]', 'Known HTTP(S) URLs to find tools for') + .option( + '--options ', + 'Catalogue selectors: providers, categories, groups, capabilities; level: providers|groups|tools; limit: 1-100; expand: options,response,examples' + ) .option( '--request ', 'A complete next request returned by Find Tools' @@ -165,21 +171,33 @@ export function createFindToolsCommand(): Command { export function addAlexandriaScrapeOptions(command: Command): void { command .addOption( - new Option('--alexandria ') - .argParser((value: string, previous: string[] = []) => [ - ...previous, - value, - ]) - .hideHelp() + new Option( + '--alexandria ', + 'Execute a discovered tool through Scrape (repeat for batches)' + ).argParser((value: string, previous: string[] = []) => [ + ...previous, + value, + ]) ) .addOption( - new Option('--options ') - .argParser((value: string, previous: string[] = []) => [ - ...previous, - value, - ]) - .hideHelp() + new Option( + '--options ', + 'Input object for each --alexandria call, in matching order' + ).argParser((value: string, previous: string[] = []) => [ + ...previous, + value, + ]) ) - .addOption(new Option('--request-id ').hideHelp()) - .addOption(new Option('--domain-tools').hideHelp()); + .addOption( + new Option( + '--request-id ', + 'Reuse the same ID only for an identical tool retry' + ) + ) + .addOption( + new Option( + '--domain-tools', + 'Discover related tools alongside URL content; does not execute them' + ) + ); } diff --git a/src/commands/search.ts b/src/commands/search.ts index 4181ed37a0..2bac898562 100644 --- a/src/commands/search.ts +++ b/src/commands/search.ts @@ -175,9 +175,6 @@ function formatSearchReadable( options: SearchOptions ): string { const lines: string[] = []; - if (data.tools?.length) { - lines.push('=== Tools ===', JSON.stringify(data.tools, null, 2), ''); - } // Format web results if (data.web && data.web.length > 0) { @@ -284,6 +281,33 @@ function formatSearchReadable( } } + if (data.tools?.length) { + lines.push('=== Alexandria Tools ===', ''); + for (const tool of data.tools) { + const address = + typeof tool.provider === 'string' && typeof tool.capability === 'string' + ? `${tool.provider}/${tool.capability}` + : undefined; + const title = tool.label ?? tool.name ?? address ?? tool.id ?? 'Tool'; + lines.push(String(title)); + if (address) lines.push(` Tool: ${address}`); + if (typeof tool.description === 'string') + lines.push(` ${clipPassage(tool.description)}`); + if (typeof tool.creditsCost === 'number') + lines.push( + ` Cost: ${tool.creditsCost} credits per ${tool.perRecord ? 'record' : 'call'}` + ); + if (Array.isArray(tool.matchedUrls) && tool.matchedUrls.length) + lines.push(` Matches: ${tool.matchedUrls.join(', ')}`); + lines.push(''); + } + lines.push( + 'Discovery only. Inspect inputs, coverage and access in --json output.', + 'Use find-tools for tool sets or missing contracts; execute selected tools with scrape --alexandria --options .', + '' + ); + } + return lines.join('\n'); } diff --git a/src/index.ts b/src/index.ts index 9132719df9..bc13112ee2 100644 --- a/src/index.ts +++ b/src/index.ts @@ -931,7 +931,7 @@ Max upload size: 50 MB */ function createSearchCommand(): Command { const searchCmd = new Command('search') - .description('Search the web using Firecrawl') + .description('Search the web and discover relevant Alexandria tools') .argument('', 'Search query') .option( '--limit ', @@ -940,7 +940,7 @@ function createSearchCommand(): Command { ) .option( '--sources ', - 'Comma-separated sources to search: web, images, news (default: web)' + 'Comma-separated sources: web, images, news, alexandria (default: web,alexandria; --sources web opts out of tools)' ) .option( '--categories ', @@ -1070,7 +1070,14 @@ function createSearchCommand(): Command { await handleSearchCommand(searchOptions); }); - searchCmd.addOption(new Option('--domain-tools').hideHelp()); + searchCmd.option( + '--domain-tools', + 'Include tools for domains in web results (on by default with Alexandria)' + ); + searchCmd.option( + '--no-domain-tools', + 'Disable domain matching; source selection still controls semantic tools' + ); return searchCmd; } @@ -2118,7 +2125,7 @@ program.addCommand(createMapCommand()); program.addCommand(createParseCommand()); program.addCommand(createMonitorCommand()); program.addCommand(createSearchCommand()); -program.addCommand(createFindToolsCommand(), { hidden: true }); +program.addCommand(createFindToolsCommand()); program.addCommand(createDeveloperCommand()); program.addCommand(createResearchCommand()); program.addCommand(createFeedbackCommand()); diff --git a/src/types/search.ts b/src/types/search.ts index 8378a60ec5..882873ccbe 100644 --- a/src/types/search.ts +++ b/src/types/search.ts @@ -17,7 +17,7 @@ export interface SearchOptions { apiUrl?: string; /** Maximum number of results (default: 5, max: 100) */ limit?: number; - /** Sources to search: web, images, news (default: web) */ + /** Sources to search: web, images, news, alexandria (CLI default: web,alexandria) */ sources?: SearchSource[]; /** Categories to filter results: github, research, pdf, developer */ categories?: SearchCategory[]; From bc0c17f90b5688efe3aefa24f16d454ae8175a71 Mon Sep 17 00:00:00 2001 From: Developers Digest <124798203+developersdigest@users.noreply.github.com> Date: Tue, 15 Sep 2026 14:40:12 -0400 Subject: [PATCH 2/2] Bump Alexandria beta to 1.23.4-alexandria-beta.5 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index bf7bceeca4..7c9dce279f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "firecrawl-cli", - "version": "1.23.4-alexandria-beta.4", + "version": "1.23.4-alexandria-beta.5", "publishConfig": { "tag": "alexandria" },