Skip to main content

web_retrieval/
lib.rs

1#![deny(warnings)]
2#![deny(clippy::all)]
3
4//! Web fetch and web search MCP tools.
5
6pub mod fetch;
7pub mod haiku;
8pub mod search;
9pub mod tools;
10pub mod types;
11
12use tokio::sync::OnceCell;
13
14/// Shared state container for web tools.
15///
16/// Wraps shared HTTP clients and lazy-initialized Anthropic client
17/// for reuse across MCP calls.
18pub struct WebTools {
19    /// Shared HTTP client for fetching web pages
20    pub(crate) http: reqwest::Client,
21    /// Exa search API client
22    pub(crate) exa: exa_async::Client<exa_async::ExaConfig>,
23    /// Lazy-initialized Anthropic client for Haiku summarization
24    pub(crate) anthropic: OnceCell<anthropic_async::Client<anthropic_async::AnthropicConfig>>,
25}
26
27impl WebTools {
28    /// Create a new `WebTools` instance with default clients.
29    ///
30    /// # Panics
31    /// Panics if the reqwest HTTP client cannot be built.
32    #[must_use]
33    pub fn new() -> Self {
34        Self {
35            http: reqwest::Client::builder()
36                .connect_timeout(std::time::Duration::from_secs(5))
37                .timeout(std::time::Duration::from_secs(30))
38                .build()
39                .expect("reqwest client"),
40            exa: exa_async::Client::new(),
41            anthropic: OnceCell::new(),
42        }
43    }
44}
45
46impl Default for WebTools {
47    fn default() -> Self {
48        Self::new()
49    }
50}
51
52/// Re-export the `build_registry` function and `WebTools` for registry consumers.
53pub use tools::build_registry;
54
55#[cfg(test)]
56impl WebTools {
57    /// Create a `WebTools` instance with a custom HTTP client for testing.
58    pub(crate) fn with_http_client(http: reqwest::Client) -> Self {
59        Self {
60            http,
61            exa: exa_async::Client::new(),
62            anthropic: OnceCell::new(),
63        }
64    }
65}