Skip to main content
Glama
patrickdappollonio

Domain Tools (WHOIS + DNS)

resolver.go3.5 kB
package resolver import ( "context" "errors" "fmt" "net" "time" "github.com/mark3labs/mcp-go/mcp" resp "github.com/patrickdappollonio/mcp-domaintools/internal/response" "github.com/patrickdappollonio/mcp-domaintools/internal/utils" ) // Config holds resolver configuration. type Config struct { Timeout time.Duration } // resolverParams represents the parameters for hostname resolution. type resolverParams struct { Hostname string `json:"hostname"` IPVersion string `json:"ip_version"` } // HandleHostnameResolution resolves a hostname to its IP addresses. func HandleHostnameResolution(ctx context.Context, request mcp.CallToolRequest, config *Config) (*mcp.CallToolResult, error) { var params resolverParams if err := request.BindArguments(&params); err != nil { return nil, fmt.Errorf("failed to parse tool input: %w", utils.ParseJSONUnmarshalError(err)) } // Validate required parameters if params.Hostname == "" { return nil, fmt.Errorf("parameter \"hostname\" is required") } // Set default IP version if not provided if params.IPVersion == "" { params.IPVersion = "ipv4" } // Create context with timeout ctxWithTimeout, cancel := context.WithTimeout(ctx, config.Timeout) defer cancel() // Initialize response maps responseData := map[string]interface{}{ "hostname": params.Hostname, "timestamp": time.Now().Format(time.RFC3339), "ip_version": params.IPVersion, "failed": false, } // Resolve based on IP version switch params.IPVersion { case "ipv4", "ipv6": addresses, err := lookupIPAddresses(ctxWithTimeout, params.Hostname, params.IPVersion) if err == nil { responseData[params.IPVersion+"_addresses"] = addresses } else if isHostNotFoundError(err) { responseData["error"] = err.Error() responseData["failed"] = true } else { return nil, fmt.Errorf("failed to resolve %s addresses: %w", params.IPVersion, err) } default: // "both" // Get IPv4 addresses ipv4Addresses, err := lookupIPAddresses(ctxWithTimeout, params.Hostname, "ipv4") if err == nil { responseData["ipv4_addresses"] = ipv4Addresses } else if isHostNotFoundError(err) { responseData["error"] = err.Error() responseData["failed"] = true } else { return nil, fmt.Errorf("failed to resolve ipv4 addresses: %w", err) } // Get IPv6 addresses ipv6Addresses, err := lookupIPAddresses(ctxWithTimeout, params.Hostname, "ipv6") if err == nil { responseData["ipv6_addresses"] = ipv6Addresses } else if isHostNotFoundError(err) { responseData["error"] = err.Error() responseData["failed"] = true } else { return nil, fmt.Errorf("failed to resolve ipv6 addresses: %w", err) } } // Use the response package to handle JSON encoding and MCP tool result creation return resp.JSON(responseData) } // isHostNotFoundError checks if the error is a DNS "host not found" type error. func isHostNotFoundError(err error) bool { var dnsErr *net.DNSError if errors.As(err, &dnsErr) { return dnsErr.IsNotFound } return false } // lookupIPAddresses handles the IP lookup for a specific IP version (IPv4 or IPv6). func lookupIPAddresses(ctx context.Context, hostname, ipVersion string) ([]string, error) { networkType := "ip4" if ipVersion == "ipv6" { networkType = "ip6" } addrs, err := net.DefaultResolver.LookupIP(ctx, networkType, hostname) if err != nil { return nil, err } result := make([]string, len(addrs)) for i, addr := range addrs { result[i] = addr.String() } return result, nil }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/patrickdappollonio/mcp-domaintools'

If you have feedback or need assistance with the MCP directory API, please join our Discord server