Skip to main content

dnslib/mcp/tools/
records.rs

1use rmcp::{ErrorData as McpError, model::*};
2
3use crate::{
4    control_plane::policy::Policy,
5    core::dns::records,
6    core::{dns::service::DnsService, error::Error},
7    mcp::{helpers::run_json, params::*},
8};
9
10pub async fn handle_list_records<C: DnsService + Send + Sync>(
11    client: &C,
12    policy: &Policy,
13    p: ListRecordsParams,
14) -> Result<CallToolResult, McpError> {
15    let zone_check = p
16        .zone
17        .as_deref()
18        .or(p.domain.as_deref())
19        .map_or(Ok(()), |zone| policy.check_zone(zone));
20    Ok(run_json(
21        "dns_list_records",
22        policy.check_read().and(zone_check),
23        async move {
24            records::query::list_records_for_query(
25                client,
26                p.domain.as_deref(),
27                p.zone.as_deref(),
28                p.all_subdomains.unwrap_or(false),
29                p.use_local_ip.unwrap_or(false),
30            )
31            .await
32            .and_then(|r| serde_json::to_value(&r).map_err(|e| Error::parse(e.to_string())))
33        },
34    )
35    .await)
36}
37
38pub async fn handle_add_record<C: DnsService + Send + Sync>(
39    client: &C,
40    policy: &Policy,
41    p: AddRecordParams,
42) -> Result<CallToolResult, McpError> {
43    Ok(run_json(
44        "dns_add_record",
45        policy.check_write().and(policy.check_zone(&p.zone)),
46        records::create_record(client, &p.zone, &p.domain, p.ttl.unwrap_or(3600), &p.record),
47    )
48    .await)
49}
50
51pub async fn handle_delete_record<C: DnsService + Send + Sync>(
52    client: &C,
53    policy: &Policy,
54    p: DeleteRecordParams,
55) -> Result<CallToolResult, McpError> {
56    let type_params = p.record.to_api_params();
57    Ok(run_json(
58        "dns_delete_record",
59        policy.check_delete().and(policy.check_zone(&p.zone)),
60        records::delete_record(client, &p.zone, &p.domain, &type_params),
61    )
62    .await)
63}