claude_agent/types/tool/
server.rs

1//! Anthropic built-in server-side tool configurations.
2
3use serde::{Deserialize, Serialize};
4
5use crate::types::citations::CitationsConfig;
6
7#[derive(Debug, Clone, Serialize, Deserialize)]
8pub struct WebSearchTool {
9    #[serde(rename = "type")]
10    pub tool_type: String,
11    pub name: String,
12    #[serde(skip_serializing_if = "Option::is_none")]
13    pub max_uses: Option<u32>,
14    #[serde(skip_serializing_if = "Option::is_none")]
15    pub allowed_domains: Option<Vec<String>>,
16    #[serde(skip_serializing_if = "Option::is_none")]
17    pub blocked_domains: Option<Vec<String>>,
18    #[serde(skip_serializing_if = "Option::is_none")]
19    pub user_location: Option<UserLocation>,
20}
21
22#[derive(Debug, Clone, Serialize, Deserialize)]
23pub struct UserLocation {
24    #[serde(rename = "type")]
25    pub location_type: String,
26    #[serde(skip_serializing_if = "Option::is_none")]
27    pub city: Option<String>,
28    #[serde(skip_serializing_if = "Option::is_none")]
29    pub region: Option<String>,
30    #[serde(skip_serializing_if = "Option::is_none")]
31    pub country: Option<String>,
32    #[serde(skip_serializing_if = "Option::is_none")]
33    pub timezone: Option<String>,
34}
35
36impl Default for WebSearchTool {
37    fn default() -> Self {
38        Self {
39            tool_type: "web_search_20250305".to_string(),
40            name: "web_search".to_string(),
41            max_uses: None,
42            allowed_domains: None,
43            blocked_domains: None,
44            user_location: None,
45        }
46    }
47}
48
49impl WebSearchTool {
50    pub fn new() -> Self {
51        Self::default()
52    }
53
54    pub fn with_max_uses(mut self, max_uses: u32) -> Self {
55        self.max_uses = Some(max_uses);
56        self
57    }
58
59    pub fn with_allowed_domains(mut self, domains: Vec<String>) -> Self {
60        self.allowed_domains = Some(domains);
61        self
62    }
63
64    pub fn with_blocked_domains(mut self, domains: Vec<String>) -> Self {
65        self.blocked_domains = Some(domains);
66        self
67    }
68
69    pub fn with_user_location(mut self, location: UserLocation) -> Self {
70        self.user_location = Some(location);
71        self
72    }
73}
74
75impl UserLocation {
76    pub fn approximate(country: impl Into<String>) -> Self {
77        Self {
78            location_type: "approximate".to_string(),
79            city: None,
80            region: None,
81            country: Some(country.into()),
82            timezone: None,
83        }
84    }
85
86    pub fn with_city(mut self, city: impl Into<String>) -> Self {
87        self.city = Some(city.into());
88        self
89    }
90
91    pub fn with_region(mut self, region: impl Into<String>) -> Self {
92        self.region = Some(region.into());
93        self
94    }
95
96    pub fn with_timezone(mut self, timezone: impl Into<String>) -> Self {
97        self.timezone = Some(timezone.into());
98        self
99    }
100}
101
102#[derive(Debug, Clone, Serialize, Deserialize)]
103pub struct WebFetchTool {
104    #[serde(rename = "type")]
105    pub tool_type: String,
106    pub name: String,
107    #[serde(skip_serializing_if = "Option::is_none")]
108    pub max_uses: Option<u32>,
109    #[serde(skip_serializing_if = "Option::is_none")]
110    pub allowed_domains: Option<Vec<String>>,
111    #[serde(skip_serializing_if = "Option::is_none")]
112    pub blocked_domains: Option<Vec<String>>,
113    #[serde(skip_serializing_if = "Option::is_none")]
114    pub max_content_tokens: Option<u32>,
115    #[serde(skip_serializing_if = "Option::is_none")]
116    pub citations: Option<CitationsConfig>,
117}
118
119impl Default for WebFetchTool {
120    fn default() -> Self {
121        Self {
122            tool_type: "web_fetch_20250910".to_string(),
123            name: "web_fetch".to_string(),
124            max_uses: None,
125            allowed_domains: None,
126            blocked_domains: None,
127            max_content_tokens: None,
128            citations: None,
129        }
130    }
131}
132
133impl WebFetchTool {
134    pub fn new() -> Self {
135        Self::default()
136    }
137
138    pub fn with_max_uses(mut self, max_uses: u32) -> Self {
139        self.max_uses = Some(max_uses);
140        self
141    }
142
143    pub fn with_allowed_domains(mut self, domains: Vec<String>) -> Self {
144        self.allowed_domains = Some(domains);
145        self
146    }
147
148    pub fn with_blocked_domains(mut self, domains: Vec<String>) -> Self {
149        self.blocked_domains = Some(domains);
150        self
151    }
152
153    pub fn with_max_content_tokens(mut self, tokens: u32) -> Self {
154        self.max_content_tokens = Some(tokens);
155        self
156    }
157
158    pub fn with_citations(mut self, enabled: bool) -> Self {
159        self.citations = Some(if enabled {
160            CitationsConfig::enabled()
161        } else {
162            CitationsConfig::disabled()
163        });
164        self
165    }
166}
167
168#[derive(Debug, Clone, Serialize)]
169#[serde(untagged)]
170pub enum ServerTool {
171    WebSearch(WebSearchTool),
172    WebFetch(WebFetchTool),
173}