dnspls-mcp 0.1.0

MCP tool vocabulary and facade for DNSpls domain intelligence
Documentation
//! Stable MCP tool vocabulary and facade for `DNSpls` domain intelligence.
//!
//! Transport implementations can evolve without changing these semantic tool
//! identities or the evidence kernel re-exported by this package.

use serde::{Deserialize, Serialize};

pub use dnspls::*;
pub use dnspls_engine as engine;
pub use dnspls_provider as provider;
pub use dnspls_snapshot as snapshot;

/// Stable names of the `DNSpls` MCP tools described by RFC 0008.
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum ToolName {
    DomainGenerate,
    DomainSearch,
    DomainVerify,
    DomainBulkScreen,
    DomainExplain,
}

impl ToolName {
    pub const ALL: [Self; 5] = [
        Self::DomainGenerate,
        Self::DomainSearch,
        Self::DomainVerify,
        Self::DomainBulkScreen,
        Self::DomainExplain,
    ];

    pub const fn as_str(self) -> &'static str {
        match self {
            Self::DomainGenerate => "domain_generate",
            Self::DomainSearch => "domain_search",
            Self::DomainVerify => "domain_verify",
            Self::DomainBulkScreen => "domain_bulk_screen",
            Self::DomainExplain => "domain_explain",
        }
    }

    pub const fn performs_live_network_io(self) -> bool {
        matches!(self, Self::DomainVerify)
    }
}

#[cfg(test)]
mod tests {
    use std::collections::BTreeSet;

    use super::*;

    #[test]
    fn tool_names_are_unique_and_stable() {
        let names = ToolName::ALL
            .map(ToolName::as_str)
            .into_iter()
            .collect::<BTreeSet<_>>();
        assert_eq!(names.len(), ToolName::ALL.len());
    }

    #[test]
    fn only_verify_is_live_by_default() {
        for tool in ToolName::ALL {
            assert_eq!(
                tool.performs_live_network_io(),
                tool == ToolName::DomainVerify
            );
        }
    }
}