Skip to main content
Glama
zoomeye-ai

ZoomEye MCP Server

Official
by zoomeye-ai

zoomeye_search

Search for internet-connected devices and websites using ZoomEye's query syntax. Filter by IP, port, domain, service, location, certificate, and more. Retrieve detailed asset information with pagination and faceted statistics.

Instructions

Search Syntax Guide

  • Search Scope covers devices (IPv4, IPv6) and websites (domains).

  • When entering a search string, the system will match keywords in "global" mode, including content from various protocols such as HTTP, SSH, FTP, etc. (e.g., HTTP/HTTPS protocol headers, body, SSL, title, and other protocol banners).

  • Search strings are case-insensitive and will be segmented for matching (the search results page provides a " segmentation" test feature). When using == for search, it enforces exact case-sensitive matching with strict syntax.

  • Please use quotes for search strings (e.g., "Cisco System" or 'Cisco System'). If the search string contains quotes, use the escape character, e.g.,"a"b". If the search string contains parentheses, use the escape character, e.g., portinfo().

The logical operators of the syntax:

  • =, Search for assets containing keywords title="knownsec" Search for websites with titles containing Knownsec's assets

  • ==, Accurate search, indicating a complete match of keywords (case sensitive), can search for data with empty values title=="knownsec" Precise search, which means exact match of keywords (case sensitive), and can search for data with empty values Search for assets with the website title "Knownsec"

  • ||, Enter "||" in the search box to indicate the logical operation of "or" service="ssh" || service="http" Search for SSH or HTTP data

  • &&, Enter "&&" in the search box to indicate the logical operation of "and" device="router" && after="2020-01-01" Search for routers after Jan 1, 2020

  • !=, Enter "!=" in the search box to indicate the logical operation of "not" country="US" && subdivisions!="new york" Search for data in united states excluding new york

  • (), Enter "()" in the search box to indicate the logical operation of "priority processing" (country="US" && port!=80) || (country="US" && title!="404 Not Found") Search excluding port 80 in US or "404 not found" in the US

  • *,Fuzzy search, use * for search title="*google" Fuzzy search, use * to search Search for assets containing Knowsec in the website title, and the title can start with any character

Grammatical keywords

  • country="CN" Search for country assets Input country abbreviations or names, e.g. country="china"

  • subdivisions="beijing" Search for assets in the specified administrative region Input in English, e.g. subdivisions="beijing"

  • city="changsha" Search for city assets Input in English, e.g. city="changsha"

  • ssl="google" Search for assets with "google" string in ssl certificate Often used to search for corresponding targets by product name and company name

  • ssl.cert.fingerprint="F3C98F223D82CC41CF83D94671CCC6C69873FABF" Search for certificate-related fingerprint assets

  • ssl.chain_count=3 Search for SSL chain count assets

  • ssl.cert.alg="SHA256-RSA" Search for signature algorithms supported by certificates

  • ssl.cert.issuer.cn="pbx.wildix.com" Search for the common domain name of the user certificate issuer

  • ssl.cert.pubkey.rsa.bits=2048 Search for rsa_bits certificate public key bit number

  • ssl.cert.pubkey.ecdsa.bits=256 Search for ecdsa_bits certificate public key bit number

  • ssl.cert.pubkey.type="RSA" Search for the public key type of the certificate

  • ssl.cert.serial="18460192207935675900910674501" Search for certificate serial number

  • ssl.cipher.bits="128" Search for encryption suite bit number

  • ssl.cipher.name="TLS_AES_128_GCM_SHA256" Search for encryption suite name

  • ssl.cipher.version="TLSv1.3" Search for encryption suite version

  • ssl.version="TLSv1.3" Search for the SSL version of the certificate

  • ssl.cert.subject.cn="example.com" Search for the common domain name of the user certificate holder

  • ssl.jarm="29d29d15d29d29d00029d29d29d29dea0f89a2e5fb09e4d8e099befed92cfa" Search for assets related to Jarm Fingerprint content

  • ssl.ja3s=45094d08156d110d8ee97b204143db14 Find assets related to specific JA3S fingerprints

  • ip="8.8.8.8" Search for assets related to the specified IPv4 address ip="2600:3c00::f03c:91ff:fefc:574a" Search for assets related to specified IPv6 address

  • cidr="52.2.254.36/24" Search for C-class assets of IP cidr="52.2.254.36/16"is the B class of the IP, cidr="52.2.254.36/8"is the A class of the IP, e.g. cidr="52.2.254.36/16" cidr="52.2.254.36/8"

  • org="Stanford University" Search for assets of related organizations Used to locate IP assets corresponding to universities, structures, and large Internet companies

  • isp="China Mobile" Search for assets of related network service providers Can be supplemented with org data

  • asn=42893 Search for IP assets related to corresponding ASN (Autonomous system number)

  • port=80 Search for related port assets Currently does not support simultaneous open multi-port target search

  • hostname="google.com" Search for assets of related IP "hostname"

  • domain="baidu.com" Search for domain-related assets Used to search domain and subdomain data

  • banner="FTP" Search by protocol messages Used for searching HTTP response header data

  • http.header="http" Search by HTTP response header Used for searching HTTP response header data

  • http.header_hash="27f9973fe57298c3b63919259877a84d" Search by the hash values calculated from HTTP header.

  • http.header.server="Nginx" Search by server of the HTTP header Used for searching the server data in HTTP response headers

  • http.header.version="1.2" Search by version number in the HTTP header

  • http.header.status_code="200" Search by HTTP response status code Search for assets with HTTP response status code 200 or other status codes, such as 302, 404, etc.

  • http.body="document" Search by HTML body

  • http.body_hash="84a18166fde3ee7e7c974b8d1e7e21b4" Search by hash value calculated from HTML body

  • app="Cisco ASA SSL VPN" Search for Cisco ASA-SSL-VPN devices For more app rules, please refer to [object Object]. Entering keywords such as "Cisco" in the search box will display related app prompts

  • service="ssh" Search for assets related to the specified service protocol Common service protocols include: http, ftp, ssh, telnet, etc. (other services can be found in the domain name sidebar aggregation display of search results)

  • device="router" Search for router-related device types Common types include router, switch, storage-misc, etc. (other types can be found in the domain name sidebar aggregation display of search results)

  • os="RouterOS" Search for related operating systems Common systems include Linux, Windows, RouterOS, IOS, JUNOS, etc. ( other systems can be found in the domain name sidebar aggregation display of search results)

  • title="Cisco" Search for data with "Cisco" in the title of the HTML content

  • industry="government" Search for assets related to the specified industry type Common industry types include technology, energy, finance, manufacturing, etc. (other types can be supplemented with org data)

  • product="Cisco" Search for assets with "Cisco" in the component information Support mainstream asset component search

  • protocol="TCP" Search for assets with the transmission protocol as TCP Common transmission protocols include TCP, UDP, TCP6, SCTP

  • is_honeypot="True" Filter for honeypot assets

  • after="2020-01-01" && port="50050" Search for assets with an update time after Jan 1, 2020 and a port 50050 Time filters need to be combined with other filters

  • before="2020-01-01" && port="50050" Search for assets with an update time before Jan 1, 2020 and a port 50050 Time filters need to be combined with other filters

Dig

  • dig="baidu.com 220.181.38.148" Search for assets with related dig content

Iconhash

  • iconhash="f3418a443e7d841097c714d69ec4bcb8" Analyze the target data by MD5 and search for assets with related content based on the icon Search for assets with the "google" icon

  • iconhash="1941681276" Analyze the target data by MMH3 and search for assets with related content based on the icon Search for assets with the "amazon" icon

Filehash

  • filehash="0b5ce08db7fb8fffe4e14d05588d49d9" Search for assets with related content based on the parsed file data Search for assets parsed with "Gitlab"

Syntax Examples:

  • Search for all assets of China Merchants Group in Arabic org="مكتب التجار الصيني" || ssl="مكتب التجار الصيني"

  • Search for Starlink devices app=Starlink || device=Starlink

  • Search for network devices running http service on port 80 port=80 && service="http"

  • Search for network devices running ssl on port 443 in Nagoya city=nagoya && port=443 && service=ssl

  • Search for network devices running Windows operating system in the United States country=us && os=windows

  • Search for devices running Microsoft NTP application app="Microsoft NTP"

  • Search for webcams in Tokyo city=tokyo && device=webcam

  • Search for industrial control devices with component 6ES7 315-2EH14-0AB0 running on port 102 port=102 && module_id=6ES7 215-1BG40-0XB0

  • Search for assets indexed after 2020-01-01 with port 50050 open after="2020-01-01" && port=50050

  • Search for assets in Delta, Canada country=Canada && city=Delta

  • Search for assets in Poland with Linux system and port 22 os=linux && port=22 && country=PL

  • Search for FTP service with hostname example service=ftp && hostname=example

  • Search for IPv4 assets is_ipv4=true

  • Search for IPv6 assets is_ipv6=true

  • Search for IP assets containing "FreeBSD", including both IPv4 and IPv6 FreeBSD && (is_ipv4=true || is_ipv6=true)

  • Search for website assets containing FreeBSD FreeBSD && is_domain=true

  • Search for assets with "Knownsec" in the body http.body="Knownsec"

  • Search for specific Header hash http.header_hash="9763f6e29aa78e7ca2179ac82decbc25"

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
qbase64YesBase64 encoded query string for ZoomEye search
pageNoView asset page number, default is 1
pagesizeNoNumber of records per page, default is 10, maximum is 1000
fieldsNoThe fields to return, separated by commas. Default: ip, port, domain, update_time
sub_typeNoData type, supports v4, v6, and web. Default is v4
facetsNoStatistical items, separated by commas if there are multiple. Supports country, subdivisions, city, product, service, device, OS, and port
ignore_cacheNoWhether to ignore the cache. Supported by Business plan and above

Implementation Reference

  • The call_tool handler in the MCP server that routes the 'zoomeye_search' tool name to the actual ZoomeyeService.query() method, extracting arguments like qbase64, page, pagesize, fields, sub_type, facets, and ignore_cache.
    case ZoomeyeTools.ZOOMEYE_SEARCH:
        qbase64 = arguments.get("qbase64")
        if not qbase64:
            raise ValueError("Missing required argument: qbase64")
    
        page = arguments.get("page", 1)
        pagesize = arguments.get("pagesize", 10)
        fields = arguments.get("fields")
        sub_type = arguments.get("sub_type")
        facets = arguments.get("facets")
        ignore_cache = arguments.get("ignore_cache")
    
        result = await zoomeye_service.query(
            qbase64=qbase64,
            page=page,
            pagesize=pagesize,
            fields=fields,
            sub_type=sub_type,
            facets=facets,
            ignore_cache=ignore_cache
        )
  • Input schema definition for the zoomeye_search tool registered in the list_tools() function. Defines required 'qbase64' string and optional fields (page, pagesize, fields, sub_type, facets, ignore_cache).
    inputSchema={
        "type": "object",
        "properties": {
            "qbase64": {
                "type": "string",
                "description": "Base64 encoded query string for ZoomEye search",
            },
            "page": {
                "type": "integer",
                "description": "View asset page number, default is 1",
                "default": 1
            },
            "pagesize": {
                "type": "integer",
                "description": "Number of records per page, default is 10, maximum is 1000",
                "default": 10,
                "maximum": 1000
            },
            "fields": {
                "type": "string",
                "description": "The fields to return, separated by commas. Default: ip, port, domain, update_time"
            },
            "sub_type": {
                "type": "string",
                "description": "Data type, supports v4, v6, and web. Default is v4",
                "enum": ["v4", "v6", "web"]
            },
            "facets": {
                "type": "string",
                "description": "Statistical items, separated by commas if there are multiple. Supports country, subdivisions, city, product, service, device, OS, and port"
            },
            "ignore_cache": {
                "type": "boolean",
                "description": "Whether to ignore the cache. Supported by Business plan and above"
            }
        },
        "required": ["qbase64"],
    },
  • Tool registration where ZoomeyeTools.ZOOMEYE_SEARCH (value 'zoomeye_search') is listed as a Tool with its description (SEARCH_SYNTAX_GUIDE) and inputSchema.
    return [
        Tool(
            name=ZoomeyeTools.ZOOMEYE_SEARCH,
            description=SEARCH_SYNTAX_GUIDE,
            inputSchema={
                "type": "object",
                "properties": {
                    "qbase64": {
                        "type": "string",
                        "description": "Base64 encoded query string for ZoomEye search",
                    },
                    "page": {
                        "type": "integer",
                        "description": "View asset page number, default is 1",
                        "default": 1
                    },
                    "pagesize": {
                        "type": "integer",
                        "description": "Number of records per page, default is 10, maximum is 1000",
                        "default": 10,
                        "maximum": 1000
                    },
                    "fields": {
                        "type": "string",
                        "description": "The fields to return, separated by commas. Default: ip, port, domain, update_time"
                    },
                    "sub_type": {
                        "type": "string",
                        "description": "Data type, supports v4, v6, and web. Default is v4",
                        "enum": ["v4", "v6", "web"]
                    },
                    "facets": {
                        "type": "string",
                        "description": "Statistical items, separated by commas if there are multiple. Supports country, subdivisions, city, product, service, device, OS, and port"
                    },
                    "ignore_cache": {
                        "type": "boolean",
                        "description": "Whether to ignore the cache. Supported by Business plan and above"
                    }
                },
                "required": ["qbase64"],
            },
        ),
  • ZoomeyeService.query() - the actual helper method that makes the HTTP POST request to the ZoomEye API (https://api.zoomeye.ai/v2/search) with the API key and query parameters.
    async def query(self, qbase64, page=1, pagesize=10, fields=None, sub_type=None, facets=None, ignore_cache=None):
        """Query ZoomEye API with the given parameters.
        
        Args:
            qbase64 (str): Base64 encoded query string.
            page (int, optional): Page number. Defaults to 1.
            pagesize (int, optional): Number of records per page. Defaults to 10.
            fields (str, optional): Fields to return, comma separated. Defaults to None.
            sub_type (str, optional): Data type (v4, v6, web). Defaults to None.
            facets (str, optional): Statistical items, comma separated. Defaults to None.
            ignore_cache (bool, optional): Whether to ignore cache. Defaults to None.
            
        Returns:
            dict: The API response data.
            
        Raises:
            ValueError: If API key is not provided or API request fails.
        """
        if not self.key:
            raise ValueError(
                "ZoomEye API key is required. Please set it via environment variable ZOOMEYE_API_KEY or pass it to the constructor.")
    
        url = "https://api.zoomeye.ai/v2/search"
        headers = {"API-KEY": self.key, "Content-Type": "application/json"}
    
        # Prepare request data
        data = {"qbase64": qbase64, "page": page, "pagesize": pagesize}
    
        # Add optional parameters if provided
        if fields:
            data["fields"] = fields
        if sub_type:
            data["sub_type"] = sub_type
        if facets:
            data["facets"] = facets
        if ignore_cache is not None:
            data["ignore_cache"] = ignore_cache
    
        try:
            client = await self.get_client()
            async with client:
                response = await client.post(url, headers=headers, json=data)
                response.raise_for_status()  # Raise exception for HTTP errors
                return response.json()
        except httpx.HTTPError as e:
            raise ValueError(f"Error querying ZoomEye API: {str(e)}")
        except json.JSONDecodeError:
            raise ValueError("Invalid JSON response from ZoomEye API")
  • Enum definition that declares ZOOMEYE_SEARCH = 'zoomeye_search' as the canonical tool name string used across registration, dispatch, and handler.
    class ZoomeyeTools(str, Enum):
        ZOOMEYE_SEARCH = "zoomeye_search"
        """Search query for ZoomEye."""
Behavior4/5

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

With no annotations, the description carries full burden. It thoroughly explains search behavior (case-insensitivity, exact matching, operators, scopes), but omits details on rate limits, authentication, or side effects. For a read-like search tool, it is largely transparent.

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

Conciseness1/5

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

The description is extremely long (multiple paragraphs of syntax manual), which is not concise. It lacks front-loading of key information and would overwhelm an AI agent.

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

Completeness2/5

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

Despite detailed search syntax, the description lacks information on return format, pagination behavior beyond parameters, error handling, and output interpretation. With a complex tool and no output schema, more context is needed.

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?

Schema description coverage is 100%, so the baseline is 3. The description adds search syntax knowledge but does not provide additional meaning for the parameters themselves (e.g., how to construct qbase64 or interpret fields).

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 that the tool searches for devices and websites on ZoomEye, and provides extensive search syntax. It distinguishes itself from sibling tools (vuldb tools) by focusing on asset search.

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

Usage Guidelines3/5

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

The description includes many search examples and syntax rules, implying usage scenarios, but it does not explicitly state when to use this tool versus alternatives, nor does it mention any prerequisites or exclusions.

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/zoomeye-ai/mcp_zoomeye'

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