Skip to main content
Glama
Cyreslab-AI

Shodan MCP Server

get_host_count

Count internet-connected devices matching a Shodan search query to analyze network exposure and identify potential security risks without using query credits.

Instructions

Get the count of hosts matching a search query without consuming query credits

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
queryYesShodan search query to count hosts for
facetsNoList of facets to include in the count results (e.g., ['country', 'org'])

Implementation Reference

  • MCP CallToolRequest handler case for 'get_host_count' tool. Validates the query parameter, extracts optional facets, calls ShodanClient.getHostCount, handles 401 unauthorized errors gracefully, and returns the JSON-formatted response.
    case "get_host_count": {
      const query = String(request.params.arguments?.query);
      if (!query) {
        throw new McpError(
          ErrorCode.InvalidParams,
          "Search query is required"
        );
      }
    
      const facets = Array.isArray(request.params.arguments?.facets)
        ? request.params.arguments?.facets.map(String)
        : [];
    
      try {
        const hostCount = await shodanClient.getHostCount(query, facets);
    
        // Check if we got an error response from the host count method
        if (hostCount.error && hostCount.status === 401) {
          return {
            content: [{
              type: "text",
              text: JSON.stringify(hostCount, null, 2)
            }]
          };
        }
    
        return {
          content: [{
            type: "text",
            text: JSON.stringify(hostCount, null, 2)
          }]
        };
      } catch (error) {
        if (error instanceof McpError) {
          throw error;
        }
        throw new McpError(
          ErrorCode.InternalError,
          `Error getting host count: ${(error as Error).message}`
        );
      }
    }
  • Core implementation in ShodanClient class that performs the API call to Shodan's /shodan/host/count endpoint to retrieve host count matching the query, optionally with facets. Handles API errors including 401 unauthorized.
    /**
     * Get host count without consuming query credits
     */
    async getHostCount(query: string, facets: string[] = []): Promise<any> {
      try {
        const params: any = { query };
        if (facets.length > 0) {
          params.facets = facets.join(',');
        }
    
        const response = await this.axiosInstance.get("/shodan/host/count", { params });
        return response.data;
      } catch (error: unknown) {
        if (axios.isAxiosError(error)) {
          if (error.response?.status === 401) {
            return {
              error: "Unauthorized: The Shodan search API requires a paid membership. Your API key does not have access to this endpoint.",
              message: "The host count functionality requires a Shodan membership subscription with API access. Please upgrade your Shodan plan to use this feature.",
              status: 401
            };
          }
          throw new McpError(
            ErrorCode.InternalError,
            `Shodan API error: ${error.response?.data?.error || error.message}`
          );
        }
        throw error;
      }
    }
  • JSON schema definition and registration for the 'get_host_count' tool in the ListToolsRequestSchema response, including input schema with required 'query' and optional 'facets' array.
      name: "get_host_count",
      description: "Get the count of hosts matching a search query without consuming query credits",
      inputSchema: {
        type: "object",
        properties: {
          query: {
            type: "string",
            description: "Shodan search query to count hosts for"
          },
          facets: {
            type: "array",
            items: {
              type: "string"
            },
            description: "List of facets to include in the count results (e.g., ['country', 'org'])"
          }
        },
        required: ["query"]
      }
    },
  • src/index.ts:875-1280 (registration)
    Registration of all tools including 'get_host_count' via the ListToolsRequestSchema handler, which returns the list of available tools with their schemas.
    server.setRequestHandler(ListToolsRequestSchema, async () => {
      return {
        tools: [
          {
            name: "get_host_info",
            description: "Get detailed information about a specific IP address",
            inputSchema: {
              type: "object",
              properties: {
                ip: {
                  type: "string",
                  description: "IP address to look up"
                },
                max_items: {
                  type: "number",
                  description: "Maximum number of items to include in arrays (default: 5)"
                },
                fields: {
                  type: "array",
                  items: {
                    type: "string"
                  },
                  description: "List of fields to include in the results (e.g., ['ip_str', 'ports', 'location.country_name'])"
                }
              },
              required: ["ip"]
            }
          },
          {
            name: "search_shodan",
            description: "Search Shodan's database for devices and services",
            inputSchema: {
              type: "object",
              properties: {
                query: {
                  type: "string",
                  description: "Shodan search query (e.g., 'apache country:US')"
                },
                page: {
                  type: "number",
                  description: "Page number for results pagination (default: 1)"
                },
                facets: {
                  type: "array",
                  items: {
                    type: "string"
                  },
                  description: "List of facets to include in the search results (e.g., ['country', 'org'])"
                },
                max_items: {
                  type: "number",
                  description: "Maximum number of items to include in arrays (default: 5)"
                },
                fields: {
                  type: "array",
                  items: {
                    type: "string"
                  },
                  description: "List of fields to include in the results (e.g., ['ip_str', 'ports', 'location.country_name'])"
                },
                summarize: {
                  type: "boolean",
                  description: "Whether to return a summary of the results instead of the full data (default: false)"
                }
              },
              required: ["query"]
            }
          },
          {
            name: "scan_network_range",
            description: "Scan a network range (CIDR notation) for devices",
            inputSchema: {
              type: "object",
              properties: {
                cidr: {
                  type: "string",
                  description: "Network range in CIDR notation (e.g., 192.168.1.0/24)"
                },
                max_items: {
                  type: "number",
                  description: "Maximum number of items to include in results (default: 5)"
                },
                fields: {
                  type: "array",
                  items: {
                    type: "string"
                  },
                  description: "List of fields to include in the results (e.g., ['ip_str', 'ports', 'location.country_name'])"
                }
              },
              required: ["cidr"]
            }
          },
          {
            name: "get_ssl_info",
            description: "Get SSL certificate information for a domain",
            inputSchema: {
              type: "object",
              properties: {
                domain: {
                  type: "string",
                  description: "Domain name to look up SSL certificates for (e.g., example.com)"
                }
              },
              required: ["domain"]
            }
          },
          {
            name: "search_iot_devices",
            description: "Search for specific types of IoT devices",
            inputSchema: {
              type: "object",
              properties: {
                device_type: {
                  type: "string",
                  description: "Type of IoT device to search for (e.g., 'webcam', 'router', 'smart tv')"
                },
                country: {
                  type: "string",
                  description: "Optional country code to limit search (e.g., 'US', 'DE')"
                },
                max_items: {
                  type: "number",
                  description: "Maximum number of items to include in results (default: 5)"
                }
              },
              required: ["device_type"]
            }
          },
          {
            name: "get_host_count",
            description: "Get the count of hosts matching a search query without consuming query credits",
            inputSchema: {
              type: "object",
              properties: {
                query: {
                  type: "string",
                  description: "Shodan search query to count hosts for"
                },
                facets: {
                  type: "array",
                  items: {
                    type: "string"
                  },
                  description: "List of facets to include in the count results (e.g., ['country', 'org'])"
                }
              },
              required: ["query"]
            }
          },
          {
            name: "list_search_facets",
            description: "List all available search facets that can be used with Shodan queries",
            inputSchema: {
              type: "object",
              properties: {}
            }
          },
          {
            name: "list_search_filters",
            description: "List all available search filters that can be used in Shodan queries",
            inputSchema: {
              type: "object",
              properties: {}
            }
          },
          {
            name: "parse_search_tokens",
            description: "Parse a search query to understand which filters and parameters are being used",
            inputSchema: {
              type: "object",
              properties: {
                query: {
                  type: "string",
                  description: "Shodan search query to parse and analyze"
                }
              },
              required: ["query"]
            }
          },
          {
            name: "list_ports",
            description: "List all ports that Shodan crawls on the Internet",
            inputSchema: {
              type: "object",
              properties: {}
            }
          },
          {
            name: "list_protocols",
            description: "List all protocols that can be used when performing on-demand Internet scans",
            inputSchema: {
              type: "object",
              properties: {}
            }
          },
          {
            name: "get_api_info",
            description: "Get information about your API plan including credits and limits",
            inputSchema: {
              type: "object",
              properties: {}
            }
          },
          {
            name: "get_my_ip",
            description: "Get your current IP address as seen from the Internet",
            inputSchema: {
              type: "object",
              properties: {}
            }
          },
          {
            name: "dns_lookup",
            description: "Resolve hostnames to IP addresses using DNS lookup",
            inputSchema: {
              type: "object",
              properties: {
                hostnames: {
                  type: "array",
                  items: {
                    type: "string"
                  },
                  description: "List of hostnames to resolve (e.g., ['google.com', 'facebook.com'])"
                }
              },
              required: ["hostnames"]
            }
          },
          {
            name: "reverse_dns_lookup",
            description: "Get hostnames for IP addresses using reverse DNS lookup",
            inputSchema: {
              type: "object",
              properties: {
                ips: {
                  type: "array",
                  items: {
                    type: "string"
                  },
                  description: "List of IP addresses to lookup (e.g., ['8.8.8.8', '1.1.1.1'])"
                }
              },
              required: ["ips"]
            }
          },
          {
            name: "get_domain_info",
            description: "Get comprehensive domain information including subdomains and DNS records",
            inputSchema: {
              type: "object",
              properties: {
                domain: {
                  type: "string",
                  description: "Domain name to lookup (e.g., 'google.com')"
                },
                history: {
                  type: "boolean",
                  description: "Include historical DNS data (default: false)"
                },
                type: {
                  type: "string",
                  description: "DNS record type filter (A, AAAA, CNAME, NS, SOA, MX, TXT)"
                },
                page: {
                  type: "number",
                  description: "Page number for pagination (default: 1)"
                }
              },
              required: ["domain"]
            }
          },
          {
            name: "get_account_profile",
            description: "Get account profile information including membership status and credits",
            inputSchema: {
              type: "object",
              properties: {}
            }
          },
          {
            name: "get_cve_info",
            description: "Get detailed information about a specific CVE",
            inputSchema: {
              type: "object",
              properties: {
                cve_id: {
                  type: "string",
                  description: "CVE ID to look up (e.g., 'CVE-2021-44228')"
                }
              },
              required: ["cve_id"]
            }
          },
          {
            name: "search_cves",
            description: "Search for vulnerabilities with various filters",
            inputSchema: {
              type: "object",
              properties: {
                cpe23: {
                  type: "string",
                  description: "CPE 2.3 string to search for (e.g., 'cpe:2.3:a:apache:log4j:*')"
                },
                product: {
                  type: "string",
                  description: "Product name to search for vulnerabilities (e.g., 'apache', 'windows')"
                },
                is_kev: {
                  type: "boolean",
                  description: "Filter for Known Exploited Vulnerabilities only"
                },
                sort_by_epss: {
                  type: "boolean",
                  description: "Sort results by EPSS score (Exploit Prediction Scoring System)"
                },
                start_date: {
                  type: "string",
                  description: "Start date for filtering CVEs (YYYY-MM-DD format)"
                },
                end_date: {
                  type: "string",
                  description: "End date for filtering CVEs (YYYY-MM-DD format)"
                },
                limit: {
                  type: "number",
                  description: "Maximum number of results to return (default: 10)"
                },
                skip: {
                  type: "number",
                  description: "Number of results to skip for pagination (default: 0)"
                }
              }
            }
          },
          {
            name: "get_cpes",
            description: "Get Common Platform Enumeration (CPE) information for products",
            inputSchema: {
              type: "object",
              properties: {
                product: {
                  type: "string",
                  description: "Product name to search for (e.g., 'apache', 'windows')"
                },
                vendor: {
                  type: "string",
                  description: "Vendor name to filter by (e.g., 'microsoft', 'apache')"
                },
                version: {
                  type: "string",
                  description: "Version to filter by (e.g., '2.4.1')"
                },
                limit: {
                  type: "number",
                  description: "Maximum number of results to return (default: 10)"
                },
                skip: {
                  type: "number",
                  description: "Number of results to skip for pagination (default: 0)"
                }
              }
            }
          },
          {
            name: "get_newest_cves",
            description: "Get the newest vulnerabilities from the CVE database",
            inputSchema: {
              type: "object",
              properties: {
                limit: {
                  type: "number",
                  description: "Maximum number of results to return (default: 10)"
                }
              }
            }
          },
          {
            name: "get_kev_cves",
            description: "Get Known Exploited Vulnerabilities (KEV) from CISA",
            inputSchema: {
              type: "object",
              properties: {
                limit: {
                  type: "number",
                  description: "Maximum number of results to return (default: 10)"
                }
              }
            }
          },
          {
            name: "get_cves_by_epss",
            description: "Get CVEs sorted by EPSS score (Exploit Prediction Scoring System)",
            inputSchema: {
              type: "object",
              properties: {
                limit: {
                  type: "number",
                  description: "Maximum number of results to return (default: 10)"
                }
              }
            }
          }
        ]
      };
    });
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden of behavioral disclosure. It adds valuable context by specifying that the tool does not consume query credits, which is a key operational trait. However, it lacks details on rate limits, authentication needs, or response format, leaving gaps in behavioral understanding.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, efficient sentence that is front-loaded with the core purpose and includes a critical behavioral detail (no credit consumption). Every word earns its place, with no redundancy or unnecessary elaboration.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's moderate complexity (2 parameters, no output schema, no annotations), the description is adequate but incomplete. It covers the purpose and a key behavioral trait but lacks details on output format, error handling, or prerequisites, which would enhance completeness for effective agent use.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema description coverage is 100%, so the schema already fully documents the two parameters (query and facets). The description does not add any additional meaning or examples beyond what the schema provides, such as clarifying query syntax or facet usage, resulting in a baseline score.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the specific action ('Get the count of hosts matching a search query') and resource ('hosts'), and explicitly distinguishes it from siblings by noting it does so 'without consuming query credits'—a unique feature among the listed tools like get_host_info or search_shodan.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides clear context for when to use this tool—to count hosts based on a Shodan search query while avoiding credit consumption. However, it does not explicitly state when not to use it or name specific alternatives among siblings, such as get_host_info for detailed host data.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

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/Cyreslab-AI/shodan-mcp-server'

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