diff --git a/public/appicons/io.pilot.firecrawl.png b/public/appicons/io.pilot.firecrawl.png new file mode 100644 index 0000000..f0e268b Binary files /dev/null and b/public/appicons/io.pilot.firecrawl.png differ diff --git a/scripts/gen-apps.mjs b/scripts/gen-apps.mjs index 55ce8a6..4d429a9 100644 --- a/scripts/gen-apps.mjs +++ b/scripts/gen-apps.mjs @@ -38,7 +38,7 @@ const CAT_HUE = Object.fromEntries(CATEGORIES.map((c) => [c.id, c.hue])); const CATMAP = { 'io.pilot.postgres': 'data', 'io.pilot.duckdb': 'data', 'io.pilot.sqlite': 'data', 'io.pilot.mysql': 'data', 'io.pilot.redis': 'data', 'io.pilot.sixtyfour': 'data', 'io.pilot.orthogonal': 'data', 'io.pilot.cosift': 'ai', 'io.telepat.ideon-free': 'ai', - 'io.pilot.plainweb': 'web', 'io.pilot.otto': 'web', 'io.pilot.bowmark': 'web', + 'io.pilot.plainweb': 'web', 'io.pilot.otto': 'web', 'io.pilot.bowmark': 'web', 'io.pilot.firecrawl': 'web', 'io.pilot.smol': 'infra', 'io.pilot.miren': 'infra', 'io.pilot.docker': 'infra', 'io.pilot.tldr': 'infra', 'io.pilot.aegis': 'security', 'io.pilot.didit': 'security', 'io.pilot.slipstream': 'finance', 'io.pilot.wallet': 'finance', @@ -69,6 +69,7 @@ const ICON_MAP = { 'io.pilot.orthogonal': { image: 'png', fit: 'cover', bg: '#e3e6df' }, 'io.pilot.agentphone': { image: 'png', fit: 'contain', bg: '#26B65A' }, 'io.pilot.primitive': { image: 'png', fit: 'cover', bg: '#111110' }, + 'io.pilot.firecrawl': { image: 'png', fit: 'contain', bg: '#0b0b0a' }, }; function relLum(hex) { @@ -96,7 +97,7 @@ function iconFor(id, hue) { const APP_IDS = [ 'io.pilot.primitive', 'io.pilot.agentphone', 'io.pilot.postgres', 'io.pilot.duckdb', 'io.pilot.sqlite', 'io.pilot.mysql', 'io.pilot.redis', 'io.pilot.sixtyfour', - 'io.pilot.cosift', 'io.telepat.ideon-free', 'io.pilot.plainweb', 'io.pilot.otto', + 'io.pilot.cosift', 'io.telepat.ideon-free', 'io.pilot.plainweb', 'io.pilot.otto', 'io.pilot.firecrawl', 'io.pilot.smol', 'io.pilot.miren', 'io.pilot.docker', 'io.pilot.aegis', 'io.pilot.slipstream', 'io.pilot.wallet', 'io.pilot.bowmark', 'io.pilot.orthogonal', 'io.pilot.didit', 'io.pilot.tldr', ]; diff --git a/src/data/app-demos.json b/src/data/app-demos.json index 5bad29a..bca3fc3 100644 --- a/src/data/app-demos.json +++ b/src/data/app-demos.json @@ -1045,5 +1045,106 @@ "next": [ "io.telepat.ideon-free ideon-free.help '{}'" ] + }, + "io.pilot.firecrawl": { + "skill": "io.pilot.firecrawl", + "title": "Full usage demo", + "when_to_use": "When you need content from the live web: read a page as clean markdown, search the web, enumerate a site's URLs, crawl a whole domain, or extract structured data from pages.", + "metered": true, + "quickstart": { + "goal": "Read any page as clean, LLM-ready markdown", + "command": "pilotctl appstore call io.pilot.firecrawl firecrawl.scrape '{\"url\":\"https://example.com\"}'", + "expect": "{\"success\":true,\"data\":{\"markdown\":\"# Example Domain\\n\\nThis domain is for use in documentation examples...\",\"metadata\":{\"title\":\"Example Domain\",\"creditsUsed\":1}}}", + "cost": "1 credit" + }, + "examples": [ + { + "title": "Check your budget first (free read)", + "command": "pilotctl appstore call io.pilot.firecrawl firecrawl.balance '{}'", + "expect": "{\"credits_remaining\":1000,\"credits_seed\":1000,\"scope\":\"per-pilot-user\"}", + "cost": "0 credits (read)" + }, + { + "title": "Search the web and get real content back", + "command": "pilotctl appstore call io.pilot.firecrawl firecrawl.search '{\"query\":\"open source web crawlers\",\"limit\":3}'", + "expect": "{\"success\":true,\"data\":{\"web\":[{\"url\":\"https://...\",\"title\":\"...\",\"description\":\"...\"}]},\"id\":\"019fc9b8-...\"}", + "cost": "2 credits" + }, + { + "title": "Enumerate a site's URLs before paying to crawl it", + "command": "pilotctl appstore call io.pilot.firecrawl firecrawl.map '{\"url\":\"https://docs.firecrawl.dev\",\"limit\":50}'", + "expect": "{\"success\":true,\"links\":[{\"url\":\"https://docs.firecrawl.dev/...\",\"title\":\"...\"}]}", + "cost": "1 credit", + "note": "Always map before a crawl: crawl defaults to 10000 pages." + }, + { + "title": "Crawl a site — async, returns a job id", + "command": "pilotctl appstore call io.pilot.firecrawl firecrawl.crawl '{\"url\":\"https://docs.firecrawl.dev\",\"limit\":10}'", + "expect": "{\"success\":true,\"id\":\"a1b2c3d4-...\",\"url\":\"https://api.firecrawl.dev/v2/crawl/a1b2c3d4-...\"}", + "cost": "20 credits", + "note": "SET limit — it defaults to 10000 pages." + }, + { + "title": "Poll the crawl until it finishes (free read)", + "command": "pilotctl appstore call io.pilot.firecrawl firecrawl.crawl_status '{\"id\":\"a1b2c3d4-...\"}'", + "expect": "{\"status\":\"completed\",\"total\":10,\"completed\":10,\"creditsUsed\":10,\"data\":[{\"markdown\":\"...\",\"metadata\":{}}]}", + "cost": "0 credits (read)" + } + ], + "cost": { + "unit": "Firecrawl credits", + "free_budget": "1000 credits per Pilot user", + "hard_cap_usd": 0, + "operations": [ + { + "op": "scrape / map / docs_search", + "price": "1 credit", + "note": "per call" + }, + { + "op": "search", + "price": "2 credits", + "note": "per query" + }, + { + "op": "ask", + "price": "3 credits", + "note": "per diagnosis" + }, + { + "op": "interact_create / monitor_create", + "price": "5 credits", + "note": "per session or monitor" + }, + { + "op": "crawl / batch_scrape / extract", + "price": "20 credits", + "note": "charged when the job is accepted; a large crawl costs more as it runs" + }, + { + "op": "agent", + "price": "50 credits", + "note": "cap it with maxCredits" + }, + { + "op": "all *_status, *_errors, list and usage reads", + "price": "0 credits", + "note": "reads are free" + } + ], + "worked_total": "This demo spends 24 of your 1000 credits (quickstart scrape 1 + search 2 + map 1 + crawl 20; both reads are free).", + "check_balance": "pilotctl appstore call io.pilot.firecrawl firecrawl.balance '{}'" + }, + "gotchas": [ + "You get 1000 credits and 2 concurrent calls. Check firecrawl.balance before a big job.", + "429 means you already have 2 calls in flight — wait, or free a slot. Browser/interact sessions hold one until stopped.", + "crawl defaults to limit 10000 and agent to maxCredits 2500 — always set them.", + "crawl/batch_scrape/extract/agent are async: they return a job id, poll the matching *_status.", + "404 on someone else's job id is intentional — jobs are isolated per Pilot user.", + "firecrawl.parse is not exposed (multipart upload); scrape a public PDF/DOCX URL instead." + ], + "next": [ + "io.pilot.firecrawl firecrawl.help '{}'" + ] } -} +} \ No newline at end of file diff --git a/src/data/app-methods.json b/src/data/app-methods.json index f9bc77c..92daec3 100644 --- a/src/data/app-methods.json +++ b/src/data/app-methods.json @@ -1814,5 +1814,313 @@ "name": "tldr.version", "summary": "Print the delivered client and tldr-client-spec version, e.g. \"tlrc v1.13.1 (implementing the tldr client specification v2.3)\". Needs no cache. This is `tldr --version`." } + ], + "io.pilot.firecrawl": [ + { + "name": "firecrawl.scrape", + "summary": "Scrape one URL into clean LLM-ready markdown (or html/links/screenshot/json).", + "example": null, + "gated": null + }, + { + "name": "firecrawl.scrape_status", + "summary": "Get the status and result of a previously started scrape job by id.", + "example": null, + "gated": null + }, + { + "name": "firecrawl.scrape_interact", + "summary": "Run code or an AI prompt in the live browser session bound to a scrape job.", + "example": null, + "gated": null + }, + { + "name": "firecrawl.scrape_interact_stop", + "summary": "Stop the interactive browser session attached to a scrape job and free its resources.", + "example": null, + "gated": null + }, + { + "name": "firecrawl.search", + "summary": "Search the web (and optionally scrape every result in one call).", + "example": null, + "gated": null + }, + { + "name": "firecrawl.search_feedback", + "summary": "Rate a search job's quality to improve future Firecrawl search results.", + "example": null, + "gated": null + }, + { + "name": "firecrawl.map", + "summary": "Discover every URL on a domain, fast — the cheap way to scope a crawl.", + "example": null, + "gated": null + }, + { + "name": "firecrawl.crawl", + "summary": "Start an async crawl of an entire site. Returns a job id — poll firecrawl.crawl_status.", + "example": null, + "gated": null + }, + { + "name": "firecrawl.crawl_status", + "summary": "Poll a crawl job: status, completed/total counts, credits used, and the scraped pages.", + "example": null, + "gated": null + }, + { + "name": "firecrawl.crawl_cancel", + "summary": "Cancel a running crawl job.", + "example": null, + "gated": null + }, + { + "name": "firecrawl.crawl_errors", + "summary": "List the pages a crawl job failed on, plus URLs blocked by robots.txt.", + "example": null, + "gated": null + }, + { + "name": "firecrawl.crawl_active", + "summary": "List every crawl currently running for your account.", + "example": null, + "gated": null + }, + { + "name": "firecrawl.crawl_params_preview", + "summary": "Dry-run: see the crawl options a natural-language prompt would generate, without spending credits.", + "example": null, + "gated": null + }, + { + "name": "firecrawl.batch_scrape", + "summary": "Scrape many known URLs in one async job. Returns a job id — poll firecrawl.batch_scrape_status.", + "example": null, + "gated": null + }, + { + "name": "firecrawl.batch_scrape_status", + "summary": "Poll a batch scrape job: progress, credits used, and the scraped pages.", + "example": null, + "gated": null + }, + { + "name": "firecrawl.batch_scrape_cancel", + "summary": "Cancel a running batch scrape job.", + "example": null, + "gated": null + }, + { + "name": "firecrawl.batch_scrape_errors", + "summary": "List the URLs a batch scrape job failed on, with per-URL error detail.", + "example": null, + "gated": null + }, + { + "name": "firecrawl.extract", + "summary": "Extract structured JSON from one or many pages using an LLM and your schema. Async — poll firecrawl.extract_status.", + "example": null, + "gated": null + }, + { + "name": "firecrawl.extract_status", + "summary": "Poll an extract job and retrieve the structured data once it completes.", + "example": null, + "gated": null + }, + { + "name": "firecrawl.agent", + "summary": "Autonomous web research: give a prompt, the agent decides what to visit and returns structured data. Async — poll firecrawl.agent_status.", + "example": null, + "gated": null + }, + { + "name": "firecrawl.agent_status", + "summary": "Poll an agent job and retrieve its result once it completes.", + "example": null, + "gated": null + }, + { + "name": "firecrawl.agent_cancel", + "summary": "Cancel a running agent job and stop it spending credits.", + "example": null, + "gated": null + }, + { + "name": "firecrawl.interact_create", + "summary": "Start a standalone browser session you drive with code — no prior scrape needed.", + "example": null, + "gated": null + }, + { + "name": "firecrawl.interact_list", + "summary": "List your standalone interact browser sessions.", + "example": null, + "gated": null + }, + { + "name": "firecrawl.interact_execute", + "summary": "Run Playwright or agent-browser code inside a standalone interact session.", + "example": null, + "gated": null + }, + { + "name": "firecrawl.interact_delete", + "summary": "Destroy a standalone interact session and release its browser.", + "example": null, + "gated": null + }, + { + "name": "firecrawl.monitor_create", + "summary": "Create a recurring check that watches pages, a whole site, or search results and alerts on meaningful change.", + "example": null, + "gated": null + }, + { + "name": "firecrawl.monitor_list", + "summary": "List your monitors.", + "example": null, + "gated": null + }, + { + "name": "firecrawl.monitor_get", + "summary": "Get one monitor's full configuration.", + "example": null, + "gated": null + }, + { + "name": "firecrawl.monitor_update", + "summary": "Update a monitor's schedule, targets, goal, or status (active/paused).", + "example": null, + "gated": null + }, + { + "name": "firecrawl.monitor_delete", + "summary": "Delete a monitor and stop its recurring checks.", + "example": null, + "gated": null + }, + { + "name": "firecrawl.monitor_run", + "summary": "Trigger a monitor check immediately instead of waiting for its schedule.", + "example": null, + "gated": null + }, + { + "name": "firecrawl.monitor_checks", + "summary": "List a monitor's past checks and what changed in each.", + "example": null, + "gated": null + }, + { + "name": "firecrawl.monitor_check", + "summary": "Get one monitor check in full, with page-level diffs.", + "example": null, + "gated": null + }, + { + "name": "firecrawl.research_papers", + "summary": "Search a purpose-built scientific paper index by natural-language query.", + "example": null, + "gated": null + }, + { + "name": "firecrawl.research_paper", + "summary": "Inspect a paper's metadata, or pass query to read its top matching full-text passages.", + "example": null, + "gated": null + }, + { + "name": "firecrawl.research_related", + "summary": "Expand a seed paper to related work — citers, references, or semantically similar papers.", + "example": null, + "gated": null + }, + { + "name": "firecrawl.research_github", + "summary": "Search GitHub issues, pull requests, discussions, and READMEs by natural-language query.", + "example": null, + "gated": null + }, + { + "name": "firecrawl.ask", + "summary": "Diagnose a failing Firecrawl call with an AI support agent — pass the jobId and get a fix.", + "example": null, + "gated": null + }, + { + "name": "firecrawl.docs_search", + "summary": "Answer a \"how does Firecrawl do X?\" question from the official docs, with citations.", + "example": null, + "gated": null + }, + { + "name": "firecrawl.feedback", + "summary": "Submit quality feedback for a completed search, scrape, parse, or map job.", + "example": null, + "gated": null + }, + { + "name": "firecrawl.credit_usage", + "summary": "Remaining credits and the current billing period.", + "example": null, + "gated": null + }, + { + "name": "firecrawl.credit_usage_historical", + "summary": "Historical credit usage over time, optionally broken down by API key.", + "example": null, + "gated": null + }, + { + "name": "firecrawl.token_usage", + "summary": "Remaining LLM tokens for extract-family operations.", + "example": null, + "gated": null + }, + { + "name": "firecrawl.token_usage_historical", + "summary": "Historical token usage over time, optionally broken down by API key.", + "example": null, + "gated": null + }, + { + "name": "firecrawl.queue_status", + "summary": "Your scrape queue depth, active jobs, and max concurrency — check before a large batch.", + "example": null, + "gated": null + }, + { + "name": "firecrawl.activity", + "summary": "Recent API activity (last 24h) with job ids you can feed to the *_status methods.", + "example": null, + "gated": null + }, + { + "name": "firecrawl.threat_protection", + "summary": "Read the account's threat-protection policy (URL risk checks, allow/deny lists).", + "example": null, + "gated": null + }, + { + "name": "firecrawl.threat_protection_update", + "summary": "Replace the account's threat-protection policy. Full-document update — unspecified fields reset to defaults.", + "example": null, + "gated": "Not available on the Pilot plan. Threat-protection policy applies to a whole Firecrawl team rather than a single caller, so it is not something an individual Pilot user can set. Upstream it is also an enterprise feature restricted to team admins." + }, + { + "name": "firecrawl.balance", + "summary": "Your remaining credits for this app, read free from the broker's per-user ledger — returns {\"credits_remaining\":,\"credits_seed\":,\"scope\":\"per-pilot-user\"}. This is YOUR balance. No partner API call, no charge. Check it before an expensive job.", + "example": null, + "gated": null + }, + { + "name": "firecrawl.help", + "summary": "Discovery: every method with params, kind, and latency class.", + "example": null, + "gated": null + } ] -} +} \ No newline at end of file diff --git a/src/data/app-overrides.json b/src/data/app-overrides.json index d7e55ec..7bf7aca 100644 --- a/src/data/app-overrides.json +++ b/src/data/app-overrides.json @@ -1122,5 +1122,57 @@ "publishedAt": null, "grants": [], "inCatalogue": true + }, + "io.pilot.firecrawl": { + "name": "Firecrawl", + "tagline": "Turn any website into clean, LLM-ready data", + "description": "**Firecrawl** turns any website into clean, LLM-ready data. This app exposes the\n**complete Firecrawl v2 API** — all 50 operations — as Pilot app-store methods,\ngenerated 1:1 from Firecrawl's published OpenAPI spec.\n\nYou do not need a Firecrawl account, an API key, an inbox, or a browser. The app is\nkeyless: Pilot's broker verifies your agent identity, meters your usage, and\nauthenticates upstream on your behalf. Install and call.\n\n**What you get**\n\n- **Scrape** — one URL to clean markdown, HTML, links, screenshots, or schema-shaped\n JSON. Handles JS-heavy pages, PDFs and Office documents, geo/proxy emulation,\n ad-blocking, and PII redaction.\n- **Search** — web, news, and image search with query-relevant highlights, domain\n and time filters, and optional full scraping of every result in the same call.\n- **Map** — enumerate every URL on a domain in about a second. The cheap way to scope\n a crawl before you pay for one.\n- **Crawl** — async whole-site extraction with include/exclude path regexes, depth and\n page limits, subdomain and external-link control, robots.txt handling, and webhooks.\n Describe the crawl in plain English and preview the generated options for free.\n- **Batch scrape** — many known URLs in one job, with per-URL error reporting.\n- **Extract** — LLM-powered structured extraction across many pages against your JSON\n Schema, optionally with web search and source citations.\n- **Agent** — autonomous web research. Give a prompt and a credit ceiling; the agent\n decides where to go and returns structured data.\n- **Interact** — drive a real browser with Playwright or natural language, either bound\n to a scrape job or as a standalone session with persistent profile storage.\n- **Monitor** — recurring checks on pages, whole sites, or web-wide searches, with an AI\n judge that filters noise against a plain-language goal, and webhook/email/Slack alerts.\n- **Research index** — search scientific papers, read their full-text passages, expand to\n related work, and search GitHub issues, PRs, and READMEs.\n- **Support** — `firecrawl.ask` diagnoses a failing job from your account's logs, and\n `firecrawl.docs_search` answers Firecrawl questions with citations.\n- **Usage** — credits, tokens, queue depth, and recent activity, so an agent can check\n cost and capacity before committing to an expensive call.\n\n**Start with `firecrawl.help`** — it returns every method with its full parameter set,\nlatency class, and measured roundtrip.\n\n**Cost control.** `firecrawl.crawl` takes `limit` and `firecrawl.agent` takes\n`maxCredits`; both default high. Set them. `firecrawl.map` and\n`firecrawl.crawl_params_preview` are the cheap ways to scope work before you spend.\nCheck `firecrawl.credit_usage` and `firecrawl.balance` before a large job.\n\n**Not exposed:** `POST /v2/parse` (upload a local file for parsing) takes\n`multipart/form-data`, which the JSON-in/JSON-out app-store IPC contract cannot\nexpress. Use `firecrawl.scrape` on a public document URL instead — it parses PDF,\nDOCX, XLSX and friends natively.\n", + "vendor": "Firecrawl", + "vendorUrl": "https://firecrawl.dev", + "license": "MIT", + "sourceUrl": "https://github.com/pilot-protocol/firecrawl-app", + "homepage": "https://firecrawl.dev", + "version": "0.1.0", + "categoriesRaw": [ + "web", + "search", + "data", + "scraping" + ], + "keywords": [ + "firecrawl", + "scrape", + "crawl", + "search", + "markdown", + "extract", + "agent", + "monitor", + "research", + "browser" + ], + "bundleBytes": 4901773, + "installedBytes": 8999266, + "changelog": [ + { + "version": "0.1.0", + "notes": [ + "Released v0.1.0" + ] + } + ], + "minPilotVersion": "1.11.0", + "runtimes": [ + "go" + ], + "protection": "shareable", + "publishedAt": "2026-08-03", + "grants": [ + "fs.read:$APP/config.json", + "key.sign:self", + "net.dial:broker.pilotprotocol.network", + "audit.log:*" + ], + "inCatalogue": true } -} +} \ No newline at end of file diff --git a/src/data/apps.ts b/src/data/apps.ts index f243d2f..3671713 100644 --- a/src/data/apps.ts +++ b/src/data/apps.ts @@ -3183,6 +3183,498 @@ export const apps: App[] = [ }, "limits": null }, + { + "id": "io.pilot.firecrawl", + "name": "Firecrawl", + "tagline": "Turn any website into clean, LLM-ready data", + "description": "**Firecrawl** turns any website into clean, LLM-ready data. This app exposes the\n**complete Firecrawl v2 API** — all 50 operations — as Pilot app-store methods,\ngenerated 1:1 from Firecrawl's published OpenAPI spec.\n\nYou do not need a Firecrawl account, an API key, an inbox, or a browser. The app is\nkeyless: Pilot's broker verifies your agent identity, meters your usage, and\nauthenticates upstream on your behalf. Install and call.\n\n**What you get**\n\n- **Scrape** — one URL to clean markdown, HTML, links, screenshots, or schema-shaped\n JSON. Handles JS-heavy pages, PDFs and Office documents, geo/proxy emulation,\n ad-blocking, and PII redaction.\n- **Search** — web, news, and image search with query-relevant highlights, domain\n and time filters, and optional full scraping of every result in the same call.\n- **Map** — enumerate every URL on a domain in about a second. The cheap way to scope\n a crawl before you pay for one.\n- **Crawl** — async whole-site extraction with include/exclude path regexes, depth and\n page limits, subdomain and external-link control, robots.txt handling, and webhooks.\n Describe the crawl in plain English and preview the generated options for free.\n- **Batch scrape** — many known URLs in one job, with per-URL error reporting.\n- **Extract** — LLM-powered structured extraction across many pages against your JSON\n Schema, optionally with web search and source citations.\n- **Agent** — autonomous web research. Give a prompt and a credit ceiling; the agent\n decides where to go and returns structured data.\n- **Interact** — drive a real browser with Playwright or natural language, either bound\n to a scrape job or as a standalone session with persistent profile storage.\n- **Monitor** — recurring checks on pages, whole sites, or web-wide searches, with an AI\n judge that filters noise against a plain-language goal, and webhook/email/Slack alerts.\n- **Research index** — search scientific papers, read their full-text passages, expand to\n related work, and search GitHub issues, PRs, and READMEs.\n- **Support** — `firecrawl.ask` diagnoses a failing job from your account's logs, and\n `firecrawl.docs_search` answers Firecrawl questions with citations.\n- **Usage** — credits, tokens, queue depth, and recent activity, so an agent can check\n cost and capacity before committing to an expensive call.\n\n**Start with `firecrawl.help`** — it returns every method with its full parameter set,\nlatency class, and measured roundtrip.\n\n**Cost control.** `firecrawl.crawl` takes `limit` and `firecrawl.agent` takes\n`maxCredits`; both default high. Set them. `firecrawl.map` and\n`firecrawl.crawl_params_preview` are the cheap ways to scope work before you spend.\nCheck `firecrawl.credit_usage` and `firecrawl.balance` before a large job.\n\n**Not exposed:** `POST /v2/parse` (upload a local file for parsing) takes\n`multipart/form-data`, which the JSON-in/JSON-out app-store IPC contract cannot\nexpress. Use `firecrawl.scrape` on a public document URL instead — it parses PDF,\nDOCX, XLSX and friends natively.\n", + "categories": [ + "web" + ], + "primaryCategory": "web", + "keywords": [ + "firecrawl", + "scrape", + "crawl", + "search", + "markdown", + "extract", + "agent", + "monitor", + "research", + "browser" + ], + "version": "0.1.0", + "vendor": "Firecrawl", + "vendorUrl": "https://firecrawl.dev", + "license": "MIT", + "sourceUrl": "https://github.com/pilot-protocol/firecrawl-app", + "homepage": "https://firecrawl.dev", + "methods": [ + { + "name": "firecrawl.scrape", + "summary": "Scrape one URL into clean LLM-ready markdown (or html/links/screenshot/json).", + "example": null, + "gated": null + }, + { + "name": "firecrawl.scrape_status", + "summary": "Get the status and result of a previously started scrape job by id.", + "example": null, + "gated": null + }, + { + "name": "firecrawl.scrape_interact", + "summary": "Run code or an AI prompt in the live browser session bound to a scrape job.", + "example": null, + "gated": null + }, + { + "name": "firecrawl.scrape_interact_stop", + "summary": "Stop the interactive browser session attached to a scrape job and free its resources.", + "example": null, + "gated": null + }, + { + "name": "firecrawl.search", + "summary": "Search the web (and optionally scrape every result in one call).", + "example": null, + "gated": null + }, + { + "name": "firecrawl.search_feedback", + "summary": "Rate a search job's quality to improve future Firecrawl search results.", + "example": null, + "gated": null + }, + { + "name": "firecrawl.map", + "summary": "Discover every URL on a domain, fast — the cheap way to scope a crawl.", + "example": null, + "gated": null + }, + { + "name": "firecrawl.crawl", + "summary": "Start an async crawl of an entire site. Returns a job id — poll firecrawl.crawl_status.", + "example": null, + "gated": null + }, + { + "name": "firecrawl.crawl_status", + "summary": "Poll a crawl job: status, completed/total counts, credits used, and the scraped pages.", + "example": null, + "gated": null + }, + { + "name": "firecrawl.crawl_cancel", + "summary": "Cancel a running crawl job.", + "example": null, + "gated": null + }, + { + "name": "firecrawl.crawl_errors", + "summary": "List the pages a crawl job failed on, plus URLs blocked by robots.txt.", + "example": null, + "gated": null + }, + { + "name": "firecrawl.crawl_active", + "summary": "List every crawl currently running for your account.", + "example": null, + "gated": null + }, + { + "name": "firecrawl.crawl_params_preview", + "summary": "Dry-run: see the crawl options a natural-language prompt would generate, without spending credits.", + "example": null, + "gated": null + }, + { + "name": "firecrawl.batch_scrape", + "summary": "Scrape many known URLs in one async job. Returns a job id — poll firecrawl.batch_scrape_status.", + "example": null, + "gated": null + }, + { + "name": "firecrawl.batch_scrape_status", + "summary": "Poll a batch scrape job: progress, credits used, and the scraped pages.", + "example": null, + "gated": null + }, + { + "name": "firecrawl.batch_scrape_cancel", + "summary": "Cancel a running batch scrape job.", + "example": null, + "gated": null + }, + { + "name": "firecrawl.batch_scrape_errors", + "summary": "List the URLs a batch scrape job failed on, with per-URL error detail.", + "example": null, + "gated": null + }, + { + "name": "firecrawl.extract", + "summary": "Extract structured JSON from one or many pages using an LLM and your schema. Async — poll firecrawl.extract_status.", + "example": null, + "gated": null + }, + { + "name": "firecrawl.extract_status", + "summary": "Poll an extract job and retrieve the structured data once it completes.", + "example": null, + "gated": null + }, + { + "name": "firecrawl.agent", + "summary": "Autonomous web research: give a prompt, the agent decides what to visit and returns structured data. Async — poll firecrawl.agent_status.", + "example": null, + "gated": null + }, + { + "name": "firecrawl.agent_status", + "summary": "Poll an agent job and retrieve its result once it completes.", + "example": null, + "gated": null + }, + { + "name": "firecrawl.agent_cancel", + "summary": "Cancel a running agent job and stop it spending credits.", + "example": null, + "gated": null + }, + { + "name": "firecrawl.interact_create", + "summary": "Start a standalone browser session you drive with code — no prior scrape needed.", + "example": null, + "gated": null + }, + { + "name": "firecrawl.interact_list", + "summary": "List your standalone interact browser sessions.", + "example": null, + "gated": null + }, + { + "name": "firecrawl.interact_execute", + "summary": "Run Playwright or agent-browser code inside a standalone interact session.", + "example": null, + "gated": null + }, + { + "name": "firecrawl.interact_delete", + "summary": "Destroy a standalone interact session and release its browser.", + "example": null, + "gated": null + }, + { + "name": "firecrawl.monitor_create", + "summary": "Create a recurring check that watches pages, a whole site, or search results and alerts on meaningful change.", + "example": null, + "gated": null + }, + { + "name": "firecrawl.monitor_list", + "summary": "List your monitors.", + "example": null, + "gated": null + }, + { + "name": "firecrawl.monitor_get", + "summary": "Get one monitor's full configuration.", + "example": null, + "gated": null + }, + { + "name": "firecrawl.monitor_update", + "summary": "Update a monitor's schedule, targets, goal, or status (active/paused).", + "example": null, + "gated": null + }, + { + "name": "firecrawl.monitor_delete", + "summary": "Delete a monitor and stop its recurring checks.", + "example": null, + "gated": null + }, + { + "name": "firecrawl.monitor_run", + "summary": "Trigger a monitor check immediately instead of waiting for its schedule.", + "example": null, + "gated": null + }, + { + "name": "firecrawl.monitor_checks", + "summary": "List a monitor's past checks and what changed in each.", + "example": null, + "gated": null + }, + { + "name": "firecrawl.monitor_check", + "summary": "Get one monitor check in full, with page-level diffs.", + "example": null, + "gated": null + }, + { + "name": "firecrawl.research_papers", + "summary": "Search a purpose-built scientific paper index by natural-language query.", + "example": null, + "gated": null + }, + { + "name": "firecrawl.research_paper", + "summary": "Inspect a paper's metadata, or pass query to read its top matching full-text passages.", + "example": null, + "gated": null + }, + { + "name": "firecrawl.research_related", + "summary": "Expand a seed paper to related work — citers, references, or semantically similar papers.", + "example": null, + "gated": null + }, + { + "name": "firecrawl.research_github", + "summary": "Search GitHub issues, pull requests, discussions, and READMEs by natural-language query.", + "example": null, + "gated": null + }, + { + "name": "firecrawl.ask", + "summary": "Diagnose a failing Firecrawl call with an AI support agent — pass the jobId and get a fix.", + "example": null, + "gated": null + }, + { + "name": "firecrawl.docs_search", + "summary": "Answer a \"how does Firecrawl do X?\" question from the official docs, with citations.", + "example": null, + "gated": null + }, + { + "name": "firecrawl.feedback", + "summary": "Submit quality feedback for a completed search, scrape, parse, or map job.", + "example": null, + "gated": null + }, + { + "name": "firecrawl.credit_usage", + "summary": "Remaining credits and the current billing period.", + "example": null, + "gated": null + }, + { + "name": "firecrawl.credit_usage_historical", + "summary": "Historical credit usage over time, optionally broken down by API key.", + "example": null, + "gated": null + }, + { + "name": "firecrawl.token_usage", + "summary": "Remaining LLM tokens for extract-family operations.", + "example": null, + "gated": null + }, + { + "name": "firecrawl.token_usage_historical", + "summary": "Historical token usage over time, optionally broken down by API key.", + "example": null, + "gated": null + }, + { + "name": "firecrawl.queue_status", + "summary": "Your scrape queue depth, active jobs, and max concurrency — check before a large batch.", + "example": null, + "gated": null + }, + { + "name": "firecrawl.activity", + "summary": "Recent API activity (last 24h) with job ids you can feed to the *_status methods.", + "example": null, + "gated": null + }, + { + "name": "firecrawl.threat_protection", + "summary": "Read the account's threat-protection policy (URL risk checks, allow/deny lists).", + "example": null, + "gated": null + }, + { + "name": "firecrawl.threat_protection_update", + "summary": "Replace the account's threat-protection policy. Full-document update — unspecified fields reset to defaults.", + "example": null, + "gated": "Not available on the Pilot plan. Threat-protection policy applies to a whole Firecrawl team rather than a single caller, so it is not something an individual Pilot user can set. Upstream it is also an enterprise feature restricted to team admins." + }, + { + "name": "firecrawl.balance", + "summary": "Your remaining credits for this app, read free from the broker's per-user ledger — returns {\"credits_remaining\":,\"credits_seed\":,\"scope\":\"per-pilot-user\"}. This is YOUR balance. No partner API call, no charge. Check it before an expensive job.", + "example": null, + "gated": null + }, + { + "name": "firecrawl.help", + "summary": "Discovery: every method with params, kind, and latency class.", + "example": null, + "gated": null + } + ], + "changelog": [ + { + "version": "0.1.0", + "notes": [ + "Released v0.1.0" + ] + } + ], + "grants": [ + "fs.read:$APP/config.json", + "key.sign:self", + "net.dial:broker.pilotprotocol.network", + "audit.log:*" + ], + "bundles": [ + { + "platform": "darwin-arm64", + "bytes": 5293915 + }, + { + "platform": "darwin-amd64", + "bytes": 5293915 + }, + { + "platform": "linux-arm64", + "bytes": 4754720 + }, + { + "platform": "linux-amd64", + "bytes": 4754720 + } + ], + "installedBytes": 8999266, + "depends": [], + "protection": "shareable", + "featured": false, + "real": true, + "inCatalogue": true, + "icon": { + "mode": "image", + "img": "/appicons/io.pilot.firecrawl.png", + "fit": "contain", + "pos": "center", + "color": "#0b0b0a", + "ink": false, + "file": null, + "hue": 200 + }, + "minPilotVersion": "1.11.0", + "runtimes": [ + "go" + ], + "publishedAt": "2026-08-03", + "updatedAt": "2026-08-03", + "productDemo": { + "skill": "io.pilot.firecrawl", + "title": "Full usage demo", + "when_to_use": "When you need content from the live web: read a page as clean markdown, search the web, enumerate a site's URLs, crawl a whole domain, or extract structured data from pages.", + "metered": true, + "quickstart": { + "goal": "Read any page as clean, LLM-ready markdown", + "command": "pilotctl appstore call io.pilot.firecrawl firecrawl.scrape '{\"url\":\"https://example.com\"}'", + "expect": "{\"success\":true,\"data\":{\"markdown\":\"# Example Domain\\n\\nThis domain is for use in documentation examples...\",\"metadata\":{\"title\":\"Example Domain\",\"creditsUsed\":1}}}", + "cost": "1 credit" + }, + "examples": [ + { + "title": "Check your budget first (free read)", + "command": "pilotctl appstore call io.pilot.firecrawl firecrawl.balance '{}'", + "expect": "{\"credits_remaining\":1000,\"credits_seed\":1000,\"scope\":\"per-pilot-user\"}", + "cost": "0 credits (read)" + }, + { + "title": "Search the web and get real content back", + "command": "pilotctl appstore call io.pilot.firecrawl firecrawl.search '{\"query\":\"open source web crawlers\",\"limit\":3}'", + "expect": "{\"success\":true,\"data\":{\"web\":[{\"url\":\"https://...\",\"title\":\"...\",\"description\":\"...\"}]},\"id\":\"019fc9b8-...\"}", + "cost": "2 credits" + }, + { + "title": "Enumerate a site's URLs before paying to crawl it", + "command": "pilotctl appstore call io.pilot.firecrawl firecrawl.map '{\"url\":\"https://docs.firecrawl.dev\",\"limit\":50}'", + "expect": "{\"success\":true,\"links\":[{\"url\":\"https://docs.firecrawl.dev/...\",\"title\":\"...\"}]}", + "cost": "1 credit", + "note": "Always map before a crawl: crawl defaults to 10000 pages." + }, + { + "title": "Crawl a site — async, returns a job id", + "command": "pilotctl appstore call io.pilot.firecrawl firecrawl.crawl '{\"url\":\"https://docs.firecrawl.dev\",\"limit\":10}'", + "expect": "{\"success\":true,\"id\":\"a1b2c3d4-...\",\"url\":\"https://api.firecrawl.dev/v2/crawl/a1b2c3d4-...\"}", + "cost": "20 credits", + "note": "SET limit — it defaults to 10000 pages." + }, + { + "title": "Poll the crawl until it finishes (free read)", + "command": "pilotctl appstore call io.pilot.firecrawl firecrawl.crawl_status '{\"id\":\"a1b2c3d4-...\"}'", + "expect": "{\"status\":\"completed\",\"total\":10,\"completed\":10,\"creditsUsed\":10,\"data\":[{\"markdown\":\"...\",\"metadata\":{}}]}", + "cost": "0 credits (read)" + } + ], + "cost": { + "unit": "Firecrawl credits", + "free_budget": "1000 credits per Pilot user", + "hard_cap_usd": 0, + "operations": [ + { + "op": "scrape / map / docs_search", + "price": "1 credit", + "note": "per call" + }, + { + "op": "search", + "price": "2 credits", + "note": "per query" + }, + { + "op": "ask", + "price": "3 credits", + "note": "per diagnosis" + }, + { + "op": "interact_create / monitor_create", + "price": "5 credits", + "note": "per session or monitor" + }, + { + "op": "crawl / batch_scrape / extract", + "price": "20 credits", + "note": "charged when the job is accepted; a large crawl costs more as it runs" + }, + { + "op": "agent", + "price": "50 credits", + "note": "cap it with maxCredits" + }, + { + "op": "all *_status, *_errors, list and usage reads", + "price": "0 credits", + "note": "reads are free" + } + ], + "worked_total": "This demo spends 24 of your 1000 credits (quickstart scrape 1 + search 2 + map 1 + crawl 20; both reads are free).", + "check_balance": "pilotctl appstore call io.pilot.firecrawl firecrawl.balance '{}'" + }, + "gotchas": [ + "You get 1000 credits and 2 concurrent calls. Check firecrawl.balance before a big job.", + "429 means you already have 2 calls in flight — wait, or free a slot. Browser/interact sessions hold one until stopped.", + "crawl defaults to limit 10000 and agent to maxCredits 2500 — always set them.", + "crawl/batch_scrape/extract/agent are async: they return a job id, poll the matching *_status.", + "404 on someone else's job id is intentional — jobs are isolated per Pilot user.", + "firecrawl.parse is not exposed (multipart upload); scrape a public PDF/DOCX URL instead." + ], + "next": [ + "io.pilot.firecrawl firecrawl.help '{}'" + ] + }, + "limits": null + }, { "id": "io.pilot.smol", "name": "Smol Machines", diff --git a/src/pages/app-store.astro b/src/pages/app-store.astro index c3af0ef..21369b7 100644 --- a/src/pages/app-store.astro +++ b/src/pages/app-store.astro @@ -17,7 +17,7 @@ const canonicalUrl = 'https://pilotprotocol.network/app-store'; const featured = featuredApps(); const hero = featured[0]; const sideFeatured = featured.slice(1, 4); -const freshPinned = ['io.pilot.primitive', 'io.pilot.didit', 'io.pilot.agentphone', 'io.pilot.orthogonal', 'io.pilot.bowmark', 'io.pilot.miren', 'io.pilot.smol', 'io.pilot.wallet', 'io.pilot.slipstream']; +const freshPinned = ['io.pilot.firecrawl', 'io.pilot.primitive', 'io.pilot.didit', 'io.pilot.agentphone', 'io.pilot.orthogonal', 'io.pilot.bowmark', 'io.pilot.miren', 'io.pilot.smol', 'io.pilot.wallet', 'io.pilot.slipstream']; const freshExclude = new Set(['io.pilot.postgres', 'io.pilot.docker']); const fresh = [ ...freshPinned.map((id) => apps.find((a) => a.id === id)).filter(Boolean), diff --git a/src/pages/plain/app-store.astro b/src/pages/plain/app-store.astro index dc19127..4c39582 100644 --- a/src/pages/plain/app-store.astro +++ b/src/pages/plain/app-store.astro @@ -1,7 +1,7 @@ --- // Auto-generated by scripts/regen-plain.mjs. Edit the marketing source and re-run. // plain-source: src/pages/app-store.astro -// plain-source-sha256: 5c3087953af2e13110f8ac610b49694b35cf295b7beea14178cb4d23286e3685 +// plain-source-sha256: 36019f7e7b97e467fbd214d12751867e09a2edcb3e74be08e92654deb3033e75 import PlainLayout from '../../layouts/PlainLayout.astro'; ---