dnslib/mcp/params.rs
1//! MCP parameter DTOs — all tool parameter structs and enums.
2
3use schemars::JsonSchema;
4use serde::Deserialize;
5
6use crate::core::dns::zones::ZoneImportOptions;
7use crate::core::dns::{
8 logs::{LogLevel, LogsOptions},
9 records::{RecordData, RecordSelector},
10};
11
12fn default_true() -> bool {
13 true
14}
15
16// ─── Shared server scope ───────────────────────────────────────────────────
17
18#[derive(Deserialize, JsonSchema)]
19pub struct ServerScopeParams {
20 /// The DNS server ID to run this command against (see dns_list_servers)
21 pub server_id: String,
22}
23
24// ─── Zone params ───────────────────────────────────────────────────────────
25
26#[derive(Deserialize, JsonSchema)]
27pub struct ZoneParams {
28 /// The DNS server ID to run this command against (see dns_list_servers)
29 pub server_id: String,
30 /// The zone name, e.g. "example.com"
31 pub zone: String,
32}
33
34#[derive(Deserialize, JsonSchema)]
35pub struct ListZonesParams {
36 /// The DNS server ID to run this command against (see dns_list_servers)
37 pub server_id: String,
38 /// Page number for pagination (default: 1)
39 pub page_number: Option<u32>,
40 /// Zones per page (default: 50)
41 pub zones_per_page: Option<u32>,
42}
43
44#[derive(Deserialize, JsonSchema)]
45pub struct CreateZoneParams {
46 /// The DNS server ID to run this command against (see dns_list_servers)
47 pub server_id: String,
48 /// Zone name, e.g. "example.com"
49 pub zone: String,
50 /// Zone type: Primary, Secondary, Stub, Forwarder
51 pub zone_type: String,
52}
53
54#[derive(Deserialize, JsonSchema)]
55pub struct ExportZoneFileParams {
56 /// The DNS server ID to run this command against (see dns_list_servers)
57 pub server_id: String,
58 /// Zone name to export, e.g. "example.com"
59 pub zone: String,
60}
61
62#[derive(Deserialize, JsonSchema)]
63pub struct ImportZoneFileParams {
64 /// The DNS server ID to run this command against (see dns_list_servers)
65 pub server_id: String,
66 /// Zone name the file will be imported into (must already exist)
67 pub zone: String,
68 /// Full RFC 1035 zone file content as a string
69 pub content: String,
70 /// Filename shown in API logs (default: zone.txt)
71 pub file_name: Option<String>,
72 #[serde(flatten)]
73 pub options: ZoneImportOptions,
74}
75
76#[derive(Deserialize, JsonSchema)]
77pub struct TransferZoneParams {
78 /// Zone name to transfer, e.g. "example.com"
79 pub zone: String,
80 /// Source server ID.
81 pub from: String,
82 /// Destination server ID.
83 pub to: String,
84 /// Overwrite existing record sets in the destination for imported types (default: true)
85 #[serde(default = "default_true")]
86 pub overwrite: bool,
87 /// Delete all existing records in the destination before importing (default: false)
88 #[serde(default)]
89 pub overwrite_zone: bool,
90}
91
92// ─── Record params ─────────────────────────────────────────────────────────
93
94#[derive(Deserialize, JsonSchema)]
95pub struct ListRecordsParams {
96 /// The DNS server ID to run this command against (see dns_list_servers)
97 pub server_id: String,
98 /// Domain to list records for. Omit to list records for all hosted zones.
99 #[serde(default)]
100 pub domain: Option<String>,
101 /// Zone name (if different from domain)
102 pub zone: Option<String>,
103 /// Also show records for every subdomain of the given domain
104 #[serde(default)]
105 pub all_subdomains: Option<bool>,
106 /// Prefer a locally-resolved private IP over the provider's public A/AAAA value
107 #[serde(default, rename = "useLocalIp", alias = "use_local_ip")]
108 pub use_local_ip: Option<bool>,
109}
110
111#[derive(Deserialize, JsonSchema)]
112pub struct AddRecordParams {
113 /// The DNS server ID to run this command against (see dns_list_servers)
114 pub server_id: String,
115 pub zone: String,
116 pub domain: String,
117 /// TTL in seconds (default: 3600)
118 pub ttl: Option<u32>,
119 /// Typed record data, e.g. {"type":"A","ip":"1.2.3.4"} or
120 /// {"type":"MX","exchange":"mail.example.com","preference":10}
121 pub record: RecordData,
122}
123
124#[derive(Deserialize, JsonSchema)]
125pub struct DeleteRecordParams {
126 /// The DNS server ID to run this command against (see dns_list_servers)
127 pub server_id: String,
128 pub zone: String,
129 pub domain: String,
130 /// Which record(s) to delete. Only the `type` field is required.
131 /// Omitting value fields deletes ALL records of that type for the domain.
132 /// e.g. {"type":"A"} deletes all A records; {"type":"A","ipAddress":"1.2.3.4"} deletes one.
133 pub record: RecordSelector,
134}
135
136#[derive(Deserialize, JsonSchema)]
137pub struct DomainParams {
138 /// The DNS server ID to run this command against (see dns_list_servers)
139 pub server_id: String,
140 pub domain: String,
141}
142
143#[derive(Deserialize, JsonSchema)]
144pub struct StatsParams {
145 /// The DNS server ID to run this command against (see dns_list_servers)
146 pub server_id: String,
147 /// LastHour, LastDay, LastWeek, LastMonth, LastYear (default: LastDay)
148 pub stats_type: Option<String>,
149}
150
151// ─── Logs params ──────────────────────────────────────────────────────────
152
153#[derive(Deserialize, JsonSchema)]
154#[serde(rename_all = "lowercase")]
155pub enum LogLevelParam {
156 Trace,
157 Debug,
158 Info,
159 Warning,
160 Error,
161 Critical,
162}
163
164impl From<LogLevelParam> for LogLevel {
165 fn from(value: LogLevelParam) -> Self {
166 match value {
167 LogLevelParam::Trace => LogLevel::Trace,
168 LogLevelParam::Debug => LogLevel::Debug,
169 LogLevelParam::Info => LogLevel::Info,
170 LogLevelParam::Warning => LogLevel::Warning,
171 LogLevelParam::Error => LogLevel::Error,
172 LogLevelParam::Critical => LogLevel::Critical,
173 }
174 }
175}
176
177#[derive(Deserialize, JsonSchema)]
178pub struct LogsParams {
179 /// The DNS server ID to run this command against (see dns_list_servers)
180 pub server_id: String,
181 /// Maximum number of log lines to return. Provider default is used when omitted.
182 pub lines: Option<u32>,
183 /// Optional provider-specific start timestamp/filter.
184 pub start: Option<String>,
185 /// Optional provider-specific end timestamp/filter.
186 pub end: Option<String>,
187 /// Minimum log level to return.
188 pub level: Option<LogLevelParam>,
189}
190
191impl From<LogsParams> for LogsOptions {
192 fn from(value: LogsParams) -> Self {
193 Self {
194 lines: value.lines,
195 start: value.start,
196 end: value.end,
197 level: value.level.map(Into::into),
198 }
199 }
200}
201
202// ─── Sync params ───────────────────────────────────────────────────────────
203
204#[derive(Deserialize, JsonSchema)]
205pub struct SyncParams {
206 /// Named sync profile from the config file.
207 #[serde(default)]
208 pub profile: Option<String>,
209 /// Source server ID, overriding the profile.
210 #[serde(default)]
211 pub from: Option<String>,
212 /// Destination server ID, overriding the profile.
213 #[serde(default)]
214 pub to: Option<String>,
215 /// Zones to sync, overriding the profile.
216 #[serde(default)]
217 pub zones: Vec<String>,
218 /// IP rewrite entries in SRC=DST form.
219 #[serde(default)]
220 pub map: Vec<String>,
221 /// Write the changes. False/default is dry-run.
222 #[serde(default)]
223 pub apply: bool,
224}
225
226// ─── Resolve params ────────────────────────────────────────────────────────
227
228/// Parameters for `dns_resolve` — the MCP equivalent of `dns query`.
229///
230/// At most one of `server_id` / `at` should be set; if both are omitted
231/// the host's system resolver is used. Transport selection mirrors the
232/// CLI: leave `transports` empty and `all_transports` unset to let the
233/// server pick the first enabled block (precedence: doh → dot → dns →
234/// doq); supply a list of transports to fan out across those; or set
235/// `all_transports = true` (requires `server_id`) to query every
236/// enabled block.
237#[derive(Deserialize, JsonSchema)]
238pub struct ResolveParams {
239 /// Name to resolve (FQDN).
240 pub domain: String,
241
242 /// Record types to look up (default: all supported standard types).
243 /// Standard mnemonics:
244 /// A, AAAA, CNAME, MX, TXT, NS, SRV, CAA, PTR, SOA, ANY.
245 #[serde(default)]
246 pub types: Option<Vec<String>>,
247
248 /// A configured [[servers]] entry to query. Matched case-
249 /// insensitively against `server.id`. Mutually exclusive with `at`.
250 #[serde(default)]
251 pub server_id: Option<String>,
252
253 /// Ad-hoc resolver. `host[:port]` or
254 /// `scheme://host[:port][/path]` (udp/tcp/dns/tls/dot/https/doh/
255 /// quic/doq). Mutually exclusive with `server_id`.
256 #[serde(default)]
257 pub at: Option<String>,
258
259 /// Subset of ["dns","dot","doh","doq"] to query. Empty means
260 /// "single best" (precedence pick) for `server_id`, or the
261 /// scheme-implied transport for `at`. Multiple values fan out.
262 #[serde(default)]
263 pub transports: Option<Vec<String>>,
264
265 /// Equivalent to specifying every transport flag. Requires
266 /// `server_id`. Mutually exclusive with non-empty `transports`.
267 #[serde(default)]
268 pub all_transports: Option<bool>,
269
270 /// Override port for ad-hoc targets only.
271 #[serde(default)]
272 pub port: Option<u16>,
273
274 /// SNI override for ad-hoc DoT/DoH/DoQ.
275 #[serde(default)]
276 pub tls_server_name: Option<String>,
277
278 /// Per-attempt timeout in milliseconds (default 5000).
279 #[serde(default)]
280 pub timeout_ms: Option<u64>,
281}