firecrawl_mcp/controller/
scrape.rs

1use anyhow::Result;
2use async_claude::define_tool;
3use firecrawl_sdk::scrape::{ScrapeFormats, ScrapeUrlInput};
4use rmcp::{handler::server::tool::parse_json_object, model::JsonObject};
5
6use super::FirecrawlMCP;
7
8pub const SCRAPE_TOOL_NAME: &str = "firecrawl_scrape";
9pub const SCRAPE_TOOL_DESCRIPTION: &str = "Scrape a single webpage with advanced options for content extraction. Supports various formats including markdown, HTML, and screenshots. Can execute custom actions like clicking or scrolling before scraping.";
10define_tool!(
11    FIRECRAWL_SCRAPE,
12    SCRAPE_TOOL_NAME,
13    SCRAPE_TOOL_DESCRIPTION,
14    ScrapeUrlInput
15);
16
17impl FirecrawlMCP {
18    pub async fn scrape(&self, input: JsonObject) -> Result<String, rmcp::Error> {
19        //deserialize the json object into a ScrapeOptions struct
20        let mut options = parse_json_object::<ScrapeUrlInput>(input)?;
21        options.options.formats = Some(vec![ScrapeFormats::Markdown]);
22
23        let result = self
24            .client
25            .scrape_url(options.url, Some(options.options))
26            .await
27            .map_err(|e| rmcp::Error::internal_error(e.to_string(), None))?;
28        Ok(result.markdown.unwrap_or_default())
29    }
30}