mcp-zoomeye-org 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,19 @@
1
+ from .server import serve
2
+
3
+
4
+ def main():
5
+ """MCP ZoomEye Server - ZoomEye search for MCP"""
6
+ import argparse
7
+ import asyncio
8
+
9
+ parser = argparse.ArgumentParser(
10
+ description="give a model the ability to handle ZoomEye queries"
11
+ )
12
+ parser.add_argument("--key", type=str, help="ZoomEye API Key")
13
+
14
+ args = parser.parse_args()
15
+ asyncio.run(serve(args.key))
16
+
17
+
18
+ if __name__ == "__main__":
19
+ main()
@@ -0,0 +1,3 @@
1
+ from mcp_zoomeye_org import main
2
+
3
+ main()
@@ -0,0 +1,203 @@
1
+ SEARCH_SYNTAX_GUIDE = """
2
+ ### Search Syntax Guide
3
+
4
+ - Search Scope covers devices (IPv4, IPv6) and websites (domains).
5
+ - When entering a search string, the system will match keywords in "global" mode, including content from various
6
+ protocols such as HTTP, SSH, FTP, etc. (e.g., HTTP/HTTPS protocol headers, body, SSL, title, and other protocol
7
+ banners).
8
+ - Search strings are case-insensitive and will be segmented for matching (the search results page provides a "
9
+ segmentation" test feature). When using == for search, it enforces exact case-sensitive matching with strict syntax.
10
+ - Please use quotes for search strings (e.g., "Cisco System" or 'Cisco System'). If the search string contains quotes,
11
+ use the escape character, e.g.,"a\"b". If the search string contains parentheses, use the escape character, e.g.,
12
+ portinfo\(\).
13
+
14
+ ### The logical operators of the syntax:
15
+
16
+ - =, Search for assets containing keywords
17
+ title="knownsec"
18
+ Search for websites with titles containing Knownsec's assets
19
+ - ==, Accurate search, indicating a complete match of keywords (case sensitive), can search for data with empty values
20
+ title=="knownsec"
21
+ Precise search, which means exact match of keywords (case sensitive), and can search for data with empty values Search
22
+ for assets with the website title "Knownsec"
23
+ - ||, Enter "||" in the search box to indicate the logical operation of "or"
24
+ service="ssh" || service="http"
25
+ Search for SSH or HTTP data
26
+ - &&, Enter "&&" in the search box to indicate the logical operation of "and"
27
+ device="router" && after="2020-01-01"
28
+ Search for routers after Jan 1, 2020
29
+ - !=, Enter "!=" in the search box to indicate the logical operation of "not"
30
+ country="US" && subdivisions!="new york"
31
+ Search for data in united states excluding new york
32
+ - (), Enter "()" in the search box to indicate the logical operation of "priority processing"
33
+ (country="US" && port!=80) || (country="US" && title!="404 Not Found")
34
+ Search excluding port 80 in US or "404 not found" in the US
35
+ - *,Fuzzy search, use * for search
36
+ title="*google"
37
+ Fuzzy search, use * to search Search for assets containing Knowsec in the website title, and the title can start with
38
+ any character
39
+
40
+ ### Grammatical keywords
41
+
42
+ #### Geographical Location Search
43
+
44
+ - country="CN" Search for country assets
45
+ Input country abbreviations or names, e.g.
46
+ country="china"
47
+ - subdivisions="beijing" Search for assets in the specified administrative region
48
+ Input in English, e.g.
49
+ subdivisions="beijing"
50
+ - city="changsha" Search for city assets
51
+ Input in English, e.g.
52
+ city="changsha"
53
+
54
+ #### Certificate Search
55
+
56
+ - ssl="google" Search for assets with "google" string in ssl certificate Often used to search for corresponding
57
+ targets by product name and company name
58
+ - ssl.cert.fingerprint="F3C98F223D82CC41CF83D94671CCC6C69873FABF" Search for certificate-related fingerprint assets
59
+ - ssl.chain_count=3 Search for SSL chain count assets
60
+ - ssl.cert.alg="SHA256-RSA" Search for signature algorithms supported by certificates
61
+ - ssl.cert.issuer.cn="pbx.wildix.com" Search for the common domain name of the user certificate issuer
62
+ - ssl.cert.pubkey.rsa.bits=2048 Search for rsa_bits certificate public key bit number
63
+ - ssl.cert.pubkey.ecdsa.bits=256 Search for ecdsa_bits certificate public key bit number
64
+ - ssl.cert.pubkey.type="RSA" Search for the public key type of the certificate
65
+ - ssl.cert.serial="18460192207935675900910674501" Search for certificate serial number
66
+ - ssl.cipher.bits="128" Search for encryption suite bit number
67
+ - ssl.cipher.name="TLS_AES_128_GCM_SHA256" Search for encryption suite name
68
+ - ssl.cipher.version="TLSv1.3" Search for encryption suite version
69
+ - ssl.version="TLSv1.3" Search for the SSL version of the certificate
70
+ - ssl.cert.subject.cn="example.com" Search for the common domain name of the user certificate holder
71
+ - ssl.jarm="29d29d15d29d29d00029d29d29d29dea0f89a2e5fb09e4d8e099befed92cfa" Search for assets related to Jarm
72
+ Fingerprint content
73
+ - ssl.ja3s=45094d08156d110d8ee97b204143db14 Find assets related to specific JA3S fingerprints
74
+
75
+ #### IP or Domain Name Related Information Search
76
+
77
+ - ip="8.8.8.8" Search for assets related to the specified IPv4 address
78
+ ip="2600:3c00::f03c:91ff:fefc:574a" Search for assets related to specified IPv6 address
79
+ - cidr="52.2.254.36/24" Search for C-class assets of IP
80
+ 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.
81
+ cidr="52.2.254.36/16"
82
+ cidr="52.2.254.36/8"
83
+ - org="Stanford University" Search for assets of related organizations Used to locate IP assets corresponding to
84
+ universities, structures, and large Internet companies
85
+ - isp="China Mobile" Search for assets of related network service providers Can be supplemented with org data
86
+ - asn=42893 Search for IP assets related to corresponding ASN (Autonomous system number)
87
+ - port=80 Search for related port assets Currently does not support simultaneous open multi-port target search
88
+ - hostname="google.com" Search for assets of related IP "hostname"
89
+ - domain="baidu.com" Search for domain-related assets Used to search domain and subdomain data
90
+
91
+ - banner="FTP" Search by protocol messages Used for searching HTTP response header data
92
+ - http.header="http" Search by HTTP response header Used for searching HTTP response header data
93
+ - http.header_hash="27f9973fe57298c3b63919259877a84d" Search by the hash values calculated from HTTP header.
94
+ - http.header.server="Nginx" Search by server of the HTTP header Used for searching the server data in HTTP response
95
+ headers
96
+ - http.header.version="1.2" Search by version number in the HTTP header
97
+ - http.header.status_code="200" Search by HTTP response status code Search for assets with HTTP response status code
98
+ 200 or other status codes, such as 302, 404, etc.
99
+ - http.body="document" Search by HTML body
100
+ - http.body_hash="84a18166fde3ee7e7c974b8d1e7e21b4" Search by hash value calculated from HTML body
101
+
102
+ #### Fingerprint Search
103
+
104
+ - app="Cisco ASA SSL VPN" Search for Cisco ASA-SSL-VPN devices For more app rules, please refer to [object Object].
105
+ Entering keywords such as "Cisco" in the search box will display related app prompts
106
+ - service="ssh" Search for assets related to the specified service protocol Common service protocols include: http,
107
+ ftp,
108
+ ssh, telnet, etc. (other services can be found in the domain name sidebar aggregation display of search results)
109
+ - device="router" Search for router-related device types Common types include router, switch, storage-misc, etc. (other
110
+ types can be found in the domain name sidebar aggregation display of search results)
111
+ - os="RouterOS" Search for related operating systems Common systems include Linux, Windows, RouterOS, IOS, JUNOS,
112
+ etc. (
113
+ other systems can be found in the domain name sidebar aggregation display of search results)
114
+ - title="Cisco" Search for data with "Cisco" in the title of the HTML content
115
+ - industry="government" Search for assets related to the specified industry type Common industry types include
116
+ technology, energy, finance, manufacturing, etc. (other types can be supplemented with org data)
117
+
118
+ - product="Cisco" Search for assets with "Cisco" in the component information Support mainstream asset component
119
+ search
120
+ - protocol="TCP" Search for assets with the transmission protocol as TCP Common transmission protocols include TCP,
121
+ UDP, TCP6, SCTP
122
+ - is_honeypot="True" Filter for honeypot assets
123
+
124
+ #### Time Node or Interval Related Search
125
+
126
+ - after="2020-01-01" && port="50050" Search for assets with an update time after Jan 1, 2020 and a port 50050 Time
127
+ filters need to be combined with other filters
128
+ - before="2020-01-01" && port="50050" Search for assets with an update time before Jan 1, 2020 and a port 50050 Time
129
+ filters need to be combined with other filters
130
+
131
+ #### Dig
132
+
133
+ - dig="baidu.com 220.181.38.148" Search for assets with related dig content
134
+
135
+ #### Iconhash
136
+
137
+ - iconhash="f3418a443e7d841097c714d69ec4bcb8" Analyze the target data by MD5 and search for assets with related content
138
+ based on the icon Search for assets with the "google" icon
139
+ - iconhash="1941681276" Analyze the target data by MMH3 and search for assets with related content based on the icon
140
+ Search for assets with the "amazon" icon
141
+
142
+ #### Filehash
143
+
144
+ - filehash="0b5ce08db7fb8fffe4e14d05588d49d9" Search for assets with related content based on the parsed file data
145
+ Search
146
+ for assets parsed with "Gitlab"
147
+
148
+ ### Syntax Examples:
149
+
150
+ - Search for all assets of China Merchants Group in Arabic
151
+ org="مكتب التجار الصيني" || ssl="مكتب التجار الصيني"
152
+
153
+ - Search for Starlink devices
154
+ app=Starlink || device=Starlink
155
+
156
+ - Search for network devices running http service on port 80
157
+ port=80 && service="http"
158
+
159
+ - Search for network devices running ssl on port 443 in Nagoya
160
+ city=nagoya && port=443 && service=ssl
161
+
162
+ - Search for network devices running Windows operating system in the United States
163
+ country=us && os=windows
164
+
165
+ - Search for devices running Microsoft NTP application
166
+ app="Microsoft NTP"
167
+
168
+ - Search for webcams in Tokyo
169
+ city=tokyo && device=webcam
170
+
171
+ - Search for industrial control devices with component 6ES7 315-2EH14-0AB0 running on port 102
172
+ port=102 && module_id=6ES7 215-1BG40-0XB0
173
+
174
+ - Search for assets indexed after 2020-01-01 with port 50050 open
175
+ after="2020-01-01" && port=50050
176
+
177
+ - Search for assets in Delta, Canada
178
+ country=Canada && city=Delta
179
+
180
+ - Search for assets in Poland with Linux system and port 22
181
+ os=linux && port=22 && country=PL
182
+
183
+ - Search for FTP service with hostname example
184
+ service=ftp && hostname=example
185
+
186
+ - Search for IPv4 assets
187
+ is_ipv4=true
188
+
189
+ - Search for IPv6 assets
190
+ is_ipv6=true
191
+
192
+ - Search for IP assets containing "FreeBSD", including both IPv4 and IPv6
193
+ FreeBSD && (is_ipv4=true || is_ipv6=true)
194
+
195
+ - Search for website assets containing FreeBSD
196
+ FreeBSD && is_domain=true
197
+
198
+ - Search for assets with "Knownsec" in the body
199
+ http.body="Knownsec"
200
+
201
+ - Search for specific Header hash
202
+ http.header_hash="9763f6e29aa78e7ca2179ac82decbc25"
203
+ """
@@ -0,0 +1,181 @@
1
+ import json
2
+ import os
3
+ from enum import Enum
4
+ from typing import Optional, Sequence
5
+
6
+ import httpx
7
+ from dotenv import load_dotenv
8
+ from mcp.server import Server
9
+ from mcp.server.stdio import stdio_server
10
+ from mcp.types import Tool, TextContent, ImageContent, EmbeddedResource
11
+
12
+ from .prompts import SEARCH_SYNTAX_GUIDE
13
+
14
+ load_dotenv()
15
+
16
+
17
+ class ZoomeyeTools(str, Enum):
18
+ ZOOMEYE_SEARCH = "zoomeye_search"
19
+ """Search query for ZoomEye."""
20
+ ZOOMEYE_VULDB_BY_ID = "zoomeye_vuldb_by_id"
21
+ """Query vulnerability by ID."""
22
+
23
+ ZOOMEYE_VULDB_BY_KEYWORD = "zoomeye_vuldb_by_keyword"
24
+ """Query vulnerability by keyword."""
25
+
26
+
27
+ def zoomeye_search(qbase64: str, page: int = 1, pagesize: int = 10, fields: str = "", sub_type: str = "",
28
+ facets: str = "", ignore_cache: bool = False):
29
+ """Search query for ZoomEye.
30
+ ### Parameters
31
+ |Parameter|Type|Required|Description|
32
+ | ----- | ----- | ----- | ----- |
33
+ |qbase64|string|true|Base64 encoded query string. For more, refer to Related references.|
34
+ |fields|string|false|The fields to return, separated by commas. Default: ip, port, domain, update_time. For more, refer to Response field description|
35
+ |sub_type|string|false|Data type, supports v4, v6, and web. Default is v4.|
36
+ |page|integer|false|View asset page number|
37
+ |pagesize|integer|false|Number of records per page, default is 10, maximum is 10,000.|
38
+ |facets|string|false|Statistical items, separated by commas if there are multiple. Supports country, subdivisions, city, product, service, device, OS, and port.|
39
+ |ignore_cache|boolean|false|Whether to ignore the cache. false, supported by Business plan and above.|
40
+ """
41
+ service = ZoomeyeService()
42
+ return service.query(qbase64=qbase64, page=page, pagesize=pagesize, fields=fields, sub_type=sub_type, facets=facets,
43
+ ignore_cache=ignore_cache)
44
+
45
+
46
+ class ZoomeyeService:
47
+ def __init__(self, key: Optional[str] = None):
48
+ self.key = key
49
+ self.base_url = "https://api.zoomeye.org"
50
+ if not self.key:
51
+ self.key = os.getenv("ZOOMEYE_API_KEY")
52
+
53
+ async def get_client(self):
54
+ proxy = None
55
+ https_proxy = os.getenv("https_proxy")
56
+ http_proxy = os.getenv("http_proxy")
57
+ if https_proxy or http_proxy:
58
+ proxy = https_proxy or http_proxy
59
+ return httpx.AsyncClient(proxy=proxy)
60
+
61
+ async def query(self, qbase64, page=1, pagesize=10, fields=None, sub_type=None, facets=None, ignore_cache=None):
62
+ """Query ZoomEye API with the given parameters.
63
+
64
+ Args:
65
+ qbase64 (str): Base64 encoded query string.
66
+ page (int, optional): Page number. Defaults to 1.
67
+ pagesize (int, optional): Number of records per page. Defaults to 10.
68
+ fields (str, optional): Fields to return, comma separated. Defaults to None.
69
+ sub_type (str, optional): Data type (v4, v6, web). Defaults to None.
70
+ facets (str, optional): Statistical items, comma separated. Defaults to None.
71
+ ignore_cache (bool, optional): Whether to ignore cache. Defaults to None.
72
+
73
+ Returns:
74
+ dict: The API response data.
75
+
76
+ Raises:
77
+ ValueError: If API key is not provided or API request fails.
78
+ """
79
+ if not self.key:
80
+ raise ValueError(
81
+ "ZoomEye API key is required. Please set it via environment variable ZOOMEYE_API_KEY or pass it to the constructor.")
82
+
83
+ url = f"{self.base_url}/v2/search"
84
+ headers = {"API-KEY": self.key, "Content-Type": "application/json"}
85
+
86
+ # Prepare request data
87
+ data = {"qbase64": qbase64, "page": page, "pagesize": pagesize}
88
+
89
+ # Add optional parameters if provided
90
+ if fields:
91
+ data["fields"] = fields
92
+ if sub_type:
93
+ data["sub_type"] = sub_type
94
+ if facets:
95
+ data["facets"] = facets
96
+ if ignore_cache is not None:
97
+ data["ignore_cache"] = ignore_cache
98
+
99
+ try:
100
+ client = await self.get_client()
101
+ async with client:
102
+ response = await client.post(url, headers=headers, json=data)
103
+ response.raise_for_status() # Raise exception for HTTP errors
104
+ return response.json()
105
+ except httpx.HTTPError as e:
106
+ raise ValueError(f"Error querying ZoomEye API: {str(e)}")
107
+ except json.JSONDecodeError:
108
+ raise ValueError("Invalid JSON response from ZoomEye API")
109
+
110
+
111
+ async def serve(key: str | None = None) -> None:
112
+ server = Server("mcp-zoomeye")
113
+ zoomeye_service = ZoomeyeService(key=key)
114
+
115
+ @server.list_tools()
116
+ async def list_tools() -> list[Tool]:
117
+ """Tool list"""
118
+ return [Tool(name=ZoomeyeTools.ZOOMEYE_SEARCH, description=SEARCH_SYNTAX_GUIDE, inputSchema={"type": "object",
119
+ "properties": {
120
+ "qbase64": {
121
+ "type": "string",
122
+ "description": "Base64 encoded query string for ZoomEye search", },
123
+ "page": {
124
+ "type": "integer",
125
+ "description": "View asset page number, default is 1",
126
+ "default": 1},
127
+ "pagesize": {
128
+ "type": "integer",
129
+ "description": "Number of records per page, default is 10, maximum is 1000",
130
+ "default": 10,
131
+ "maximum": 1000},
132
+ "fields": {
133
+ "type": "string",
134
+ "description": "The fields to return, separated by commas. Default: ip, port, domain, update_time"},
135
+ "sub_type": {
136
+ "type": "string",
137
+ "description": "Data type, supports v4, v6, and web. Default is v4",
138
+ "enum": [
139
+ "v4",
140
+ "v6",
141
+ "web"]},
142
+ "facets": {
143
+ "type": "string",
144
+ "description": "Statistical items, separated by commas if there are multiple. Supports country, subdivisions, city, product, service, device, OS, and port"},
145
+ "ignore_cache": {
146
+ "type": "boolean",
147
+ "description": "Whether to ignore the cache. Supported by Business plan and above"}},
148
+ "required": [
149
+ "qbase64"], }, )]
150
+
151
+ @server.call_tool()
152
+ async def call_tool(name: str, arguments: dict) -> Sequence[TextContent | ImageContent | EmbeddedResource]:
153
+ """Handle tool calls for zoomeye queries."""
154
+ try:
155
+ match name:
156
+ case ZoomeyeTools.ZOOMEYE_SEARCH:
157
+ qbase64 = arguments.get("qbase64")
158
+ if not qbase64:
159
+ raise ValueError("Missing required argument: qbase64")
160
+
161
+ page = arguments.get("page", 1)
162
+ pagesize = arguments.get("pagesize", 10)
163
+ fields = arguments.get("fields")
164
+ sub_type = arguments.get("sub_type")
165
+ facets = arguments.get("facets")
166
+ ignore_cache = arguments.get("ignore_cache")
167
+
168
+ result = await zoomeye_service.query(qbase64=qbase64, page=page, pagesize=pagesize, fields=fields,
169
+ sub_type=sub_type, facets=facets, ignore_cache=ignore_cache)
170
+ case _:
171
+ raise ValueError(f"Unknown tool: {name}")
172
+
173
+ formatted_result = json.dumps(result, ensure_ascii=False, indent=2)
174
+ return [TextContent(type="text", text=formatted_result if result is not None else "")]
175
+
176
+ except Exception as e:
177
+ raise ValueError(f"Error processing mcp-zoomeye-org query: {str(e)}")
178
+
179
+ options = server.create_initialization_options()
180
+ async with stdio_server() as (read_stream, write_stream):
181
+ await server.run(read_stream, write_stream, options)
@@ -0,0 +1,440 @@
1
+ Metadata-Version: 2.4
2
+ Name: mcp-zoomeye-org
3
+ Version: 0.1.0
4
+ Summary: A Model Context Protocol server providing tools for ZoomEye queries for LLMs
5
+ Author-email: zoomeye team <zoomeye@knownsec.com>
6
+ License: MIT
7
+ Keywords: llm,mcp,zoomeye
8
+ Classifier: Development Status :: 4 - Beta
9
+ Classifier: Intended Audience :: Developers
10
+ Classifier: License :: OSI Approved :: MIT License
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Programming Language :: Python :: 3.10
13
+ Requires-Python: >=3.10
14
+ Requires-Dist: mcp>=1.0.0
15
+ Requires-Dist: pydantic>=2.0.0
16
+ Requires-Dist: python-dotenv>=1.0.0
17
+ Requires-Dist: requests>=2.32.3
18
+ Description-Content-Type: text/markdown
19
+
20
+ # 🚀 ZoomEye MCP Server
21
+
22
+ A Model Context Protocol (MCP) server that provides network asset information based on query conditions. This server allows Large Language Models (LLMs) to obtain network asset information by querying ZoomEye using dorks and other search parameters.
23
+
24
+ ## 🔔 Announcement
25
+
26
+ 🎉 We are excited to announce the official open-source release of **ZoomEye MCP Server** — a powerful Model Context Protocol (MCP) server that brings real-time cyber asset intelligence to AI assistants and development environments.
27
+
28
+ 🚀 Free Trial: 7-Day FREE Access to ZoomEye MCP!
29
+ Experience ZoomEye MCP — the AI-powered cyberspace asset search engine — absolutely free for 7 days!
30
+
31
+ 🔍 Search global internet assets, track real-time changes, and unlock AI-driven insights — all in one place.
32
+
33
+ 👉 How to claim:
34
+
35
+ 1. Follow us on Twitter: [@zoomeye_team](https://x.com/zoomeye_team)
36
+ 2. DM us "MCP" and your MCP setup screenshot
37
+ 3. Get instant access to your 7-day membership
38
+
39
+ 🎁 Limited-time free trial — explore the power of AI asset search today!
40
+
41
+ 💡 Provide insightful feedback that gets officially adopted, and you'll unlock **even more rewards**!
42
+
43
+ 🔧 Fully compatible with leading MCP environments:
44
+
45
+ - Claude Desktop
46
+ - Cursor
47
+ - Windsurf
48
+ - Cline
49
+ - Continue
50
+ - Zed
51
+ - Cherry Studio
52
+ - Chatbox
53
+
54
+ 🔗 Explore ZoomEye MCP Server on:
55
+
56
+ - GitHub: [knownsec/mcp_zoomeye_org](https://github.com/knownsec/mcp_zoomeye_org)
57
+ - MCP.so: [mcp.so/server/mcp_zoomeye](https://mcp.so/server/mcp_zoomeye/zoomeye-ai)
58
+ - Smithery: [smithery.ai/server/@zoomeye-ai/mcp_zoomeye](https://smithery.ai/server/@zoomeye-ai/mcp_zoomeye)
59
+ - Cursor Directory: [cursor.directory/mcp/zoomeye](https://cursor.directory/mcp/zoomeye)
60
+ - Pulse MCP: [pulsemcp.com/servers/zoomeye](https://www.pulsemcp.com/servers/zoomeye)
61
+ - Glama MCP: [glama.ai/mcp/servers](https://glama.ai/mcp/servers)
62
+
63
+ We welcome everyone to use, explore, and contribute!
64
+
65
+ ## 🔑 How can I get a ZoomEye API key?
66
+
67
+ To use this MCP server, you’ll need a ZoomEye API key.
68
+
69
+ 1. Go to https://www.zoomeye.org
70
+ 2. Register or log in
71
+ 3. Click your avatar → **Profile**
72
+ 4. Copy your **API-KEY**
73
+ 5. Set the environment variable:
74
+
75
+ `export ZOOMEYE_API_KEY="your_api_key_here"`
76
+
77
+ ![zoomeye1](./zoomeye1.png)
78
+
79
+ ![zoomeye2](./zoomeye2.png)
80
+
81
+ ## Features
82
+
83
+ - Query ZoomEye for network asset information using dorks
84
+ - Caching mechanism to improve performance and reduce API calls
85
+ - Automatic retry mechanism for failed API requests
86
+ - Comprehensive error handling and logging
87
+
88
+ ## Available Tools
89
+
90
+ - `zoomeye_search` - Get network asset information based on query conditions.
91
+ - Required parameters:
92
+ - `qbase64` (string): Base64 encoded query string for ZoomEye search
93
+ - Optional parameters:
94
+ - `page` (integer): View asset page number, default is 1
95
+ - `pagesize` (integer): Number of records per page, default is 10, maximum is 1000
96
+ - `fields` (string): The fields to return, separated by commas
97
+ - `sub_type` (string): Data type, supports v4, v6, and web. Default is v4
98
+ - `facets` (string): Statistical items, separated by commas if there are multiple
99
+ - `ignore_cache` (boolean): Whether to ignore the cache
100
+
101
+ ## Usage Guide
102
+
103
+ ### Basic Usage
104
+
105
+ Once the server is running, you can interact with it through your AI assistant or development environment. Here's how to use it:
106
+
107
+ 1. **Start the server** using one of the installation methods above
108
+ 2. **Configure your AI assistant** (Claude Desktop, Cursor, Windsurf, Cline, Continue, Zed, etc.) to use the server
109
+ 3. **Query network information** using natural language
110
+
111
+ ![searchexample](example.png)
112
+
113
+ ### Search Syntax Guide
114
+
115
+ - Search Scope covers devices (IPv4, IPv6) and websites (domains).
116
+ - When entering a search string, the system will match keywords in "global" mode, including content from various
117
+ protocols such as HTTP, SSH, FTP, etc. (e.g., HTTP/HTTPS protocol headers, body, SSL, title, and other protocol
118
+ banners).
119
+ - Search strings are case-insensitive and will be segmented for matching (the search results page provides a "
120
+ segmentation" test feature). When using == for search, it enforces exact case-sensitive matching with strict syntax.
121
+ - Please use quotes for search strings (e.g., "Cisco System" or 'Cisco System'). If the search string contains quotes,
122
+ use the escape character, e.g.,"a\"b". If the search string contains parentheses, use the escape character, e.g.,
123
+ portinfo\(\).
124
+
125
+ You can see more detailed search syntax rules in [prompts.py](src/mcp_zoomeye_org/prompts.py).
126
+
127
+ For more information on the ZoomEye Search API, refer to the [ZoomEye API v2 documentation](https://www.zoomeye.org/doc).
128
+
129
+ ## Getting Started
130
+
131
+ ### Prerequisites
132
+
133
+ 1. **ZoomEye API Key**
134
+
135
+ - Register for an account at [ZoomEye](https://www.zoomeye.org/)
136
+ - Obtain your API key from your account settings
137
+ - The API key will be used to authenticate your requests to the ZoomEye API
138
+ 2. **Python Environment**
139
+
140
+ - Python 3.10 or higher is required
141
+ - Alternatively, you can use Docker to run the server without installing Python
142
+
143
+ ## Installation
144
+
145
+ ### Using PIP
146
+
147
+ Alternatively, you can install `mcp-zoomeye-org` via pip:
148
+
149
+ ```bash
150
+ pip install mcp-zoomeye-org
151
+ ```
152
+
153
+ After installation, you can run it as a script using the following command:
154
+
155
+ ```bash
156
+ python -m mcp_zoomeye_org
157
+ ```
158
+
159
+ ### Using uv
160
+
161
+ [`uv`](https://docs.astral.sh/uv/) is a fast Python package installer and resolver written in Rust. It's a modern alternative to pip that offers significant performance improvements.
162
+
163
+ #### Installation of uv
164
+
165
+ ```bash
166
+ # Install uv using curl (macOS/Linux)
167
+ curl -LsSf https://astral.sh/uv/install.sh | sh
168
+
169
+ # Or using PowerShell (Windows)
170
+ irm https://astral.sh/uv/install.ps1 | iex
171
+
172
+ # Or using Homebrew (macOS)
173
+ brew install uv
174
+ ```
175
+
176
+ #### Using uvx to run mac-zoomeye-org
177
+
178
+ No specific installation is required when using [`uvx`](https://docs.astral.sh/uv/guides/tools/), which allows you to run Python packages directly:
179
+
180
+ #### Installing with uv
181
+
182
+ Alternatively, you can install the package using uv:
183
+
184
+ ```bash
185
+ # Install in the current environment
186
+ uv pip install mac-zoomeye-org
187
+
188
+ # Or create and install in a new virtual environment
189
+ uv venv
190
+ uv pip install mac-zoomeye-org
191
+ ```
192
+
193
+ ## Configuration
194
+
195
+ ### Environment Variables
196
+
197
+ The ZoomEye MCP server requires the following environment variable:
198
+
199
+ - `ZOOMEYE_API_KEY`: Your ZoomEye API key for authentication
200
+
201
+ You can set this environment variable in several ways:
202
+
203
+ 1. **Export in your shell session**:
204
+
205
+ ```bash
206
+ export ZOOMEYE_API_KEY="your_api_key_here"
207
+ ```
208
+
209
+ ### Configure Claude.app
210
+
211
+ Add the following in Claude settings:
212
+
213
+ <details>
214
+ <summary>Using uvx</summary>
215
+
216
+ ```json
217
+ "mcpServers": {
218
+ "zoomeye": {
219
+ "command": "uvx",
220
+ "args": ["mac-zoomeye-org"],
221
+ "env": {
222
+ "ZOOMEYE_API_KEY": "your_api_key_here"
223
+ }
224
+ }
225
+ }
226
+ ```
227
+
228
+ </details>
229
+
230
+
231
+ <details>
232
+ <summary>Installed via pip</summary>
233
+
234
+ ```json
235
+ "mcpServers": {
236
+ "zoomeye": {
237
+ "command": "python",
238
+ "args": ["-m", "mcp_server_zoomeye"],
239
+ "env": {
240
+ "ZOOMEYE_API_KEY": "your_api_key_here"
241
+ }
242
+ }
243
+ }
244
+ ```
245
+
246
+ </details>
247
+
248
+ ### Configure Zed
249
+
250
+ Add the following in Zed's settings.json:
251
+
252
+ <details>
253
+ <summary>Using uvx</summary>
254
+
255
+ ```json
256
+ "context_servers": [
257
+ "mac-zoomeye-org": {
258
+ "command": "uvx",
259
+ "args": ["mac-zoomeye-org"],
260
+ "env": {
261
+ "ZOOMEYE_API_KEY": "your_api_key_here"
262
+ }
263
+ }
264
+ ],
265
+ ```
266
+
267
+ </details>
268
+
269
+ <details>
270
+ <summary>Installed via pip</summary>
271
+
272
+ ```json
273
+ "context_servers": {
274
+ "mac-zoomeye-org": {
275
+ "command": "python",
276
+ "args": ["-m", "mcp_server_zoomeye"],
277
+ "env": {
278
+ "ZOOMEYE_API_KEY": "your_api_key_here"
279
+ }
280
+ }
281
+ },
282
+ ```
283
+
284
+ </details>
285
+
286
+ ## Example Interactions
287
+
288
+ ### Example 1: Retrieve global Apache Tomcat assets
289
+
290
+ ```json
291
+ {
292
+ "name": "zoomeye_search",
293
+ "arguments": {
294
+ "qbase64": "app=\"Apache Tomcat\""
295
+ }
296
+ }
297
+ ```
298
+
299
+ Response:
300
+
301
+ ```json
302
+ {
303
+ "code": 60000,
304
+ "message": "success",
305
+ "total": 163139107,
306
+ "query": "app=\"Apache Tomcat\"",
307
+ "data": [
308
+ {
309
+ "url": "https://1.1.1.1:443",
310
+ "ssl.jarm": "29d29d15d29d29d00029d29d29d29dea0f89a2e5fb09e4d8e099befed92cfa",
311
+ "ssl.ja3s": "45094d08156d110d8ee97b204143db14",
312
+ "iconhash_md5": "f3418a443e7d841097c714d69ec4bcb8",
313
+ "robots_md5": "0b5ce08db7fb8fffe4e14d05588d49d9",
314
+ "security_md5": "0b5ce08db7fb8fffe4e14d05588d49d9",
315
+ "ip": "1.1.1.1",
316
+ "domain": "www.google.com",
317
+ "hostname": "SPACEX",
318
+ "os": "windows",
319
+ "port": 443,
320
+ "service": "https",
321
+ "title": ["GoogleGoogle appsGoogle Search"],
322
+ "version": "1.1.0",
323
+ "device": "webcam",
324
+ "rdns": "c01031-001.cust.wallcloud.ch",
325
+ "product": "OpenSSD",
326
+ "header": "HTTP/1.1 302 Found Location: https://www.google.com/?gws_rd=ssl Cache-Control: private...",
327
+ "header_hash": "27f9973fe57298c3b63919259877a84d",
328
+ "body": "HTTP/1.1 302 Found Location: https://www.google.com/?gws_rd=ssl Cache-Control: private...",
329
+ "body_hash": "84a18166fde3ee7e7c974b8d1e7e21b4",
330
+ "banner": "SSH-2.0-OpenSSH_7.6p1 Ubuntu-4ubuntu0.3",
331
+ "update_time": "2024-07-03T14:34:10",
332
+ "header.server.name": "nginx",
333
+ "header.server.version": "1.8.1",
334
+ "continent.name": "Europe",
335
+ "country.name": "Germany",
336
+ "province.name": "Hesse",
337
+ "city.name": "Frankfurt",
338
+ "lon": "118.753262",
339
+ "lat": "32.064838",
340
+ "isp.name": "aviel.ru",
341
+ "organization.name": "SERVISFIRST BANK",
342
+ "zipcode": "210003",
343
+ "idc": 0,
344
+ "honeypot": 0,
345
+ "asn": 4837,
346
+ "protocol": "tcp",
347
+ "ssl": "SSL Certificate Version: TLS 1.2 CipherSuit: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256...",
348
+ "primary_industry": "Finance",
349
+ "sub_industry": "bank",
350
+ "rank": 60
351
+ }
352
+ ]
353
+ }
354
+ ```
355
+
356
+ ## Debugging and Troubleshooting
357
+
358
+ ### Using MCP Inspector
359
+
360
+ The Model Context Protocol Inspector is a tool that helps debug MCP servers by simulating client interactions. You can use it to test your ZoomEye MCP server:
361
+
362
+ ```bash
363
+ # For uvx installation
364
+ npx @modelcontextprotocol/inspector uvx mac-zoomeye-org
365
+
366
+ # If developing locally
367
+ cd path/to/servers/src/mcp_server_zoomeye
368
+ npx @modelcontextprotocol/inspector uv run mac-zoomeye-org
369
+ ```
370
+
371
+ ### Common Issues
372
+
373
+ 1. **Authentication Errors**
374
+
375
+ - Ensure your ZoomEye API key is correct and properly set as an environment variable
376
+ - Check that your API key has not expired or been revoked
377
+ 2. **Connection Issues**
378
+
379
+ - Verify your internet connection
380
+ - Check if the ZoomEye API is experiencing downtime
381
+ 3. **No Results**
382
+
383
+ - Your query might be too specific or contain syntax errors
384
+ - Try simplifying your query or using different search terms
385
+ 4. **Rate Limiting**
386
+
387
+ - ZoomEye API has rate limits based on your account type
388
+ - Space out your requests or upgrade your account for higher limits
389
+
390
+ ## Advanced Usage
391
+
392
+ ### Caching
393
+
394
+ The ZoomEye MCP server implements caching to improve performance and reduce API calls:
395
+
396
+ - Responses are cached based on the query parameters
397
+ - Cache duration is configurable (default: 1 hour)
398
+ - You can bypass the cache by setting `ignore_cache` to `true` in your query
399
+
400
+ ### Custom Fields
401
+
402
+ You can request specific fields in your query results by using the `fields` parameter:
403
+
404
+ ```json
405
+ {
406
+ "name": "zoomeye_search",
407
+ "arguments": {
408
+ "qbase64": "app=\"Apache\"",
409
+ "fields": "ip,port,domain,service,os,country,city"
410
+ }
411
+ }
412
+ ```
413
+
414
+ ### Pagination
415
+
416
+ For queries that return many results, you can paginate through them:
417
+
418
+ ```json
419
+ {
420
+ "name": "zoomeye_search",
421
+ "arguments": {
422
+ "qbase64": "app=\"Apache\"",
423
+ "page": 2,
424
+ "pagesize": 20
425
+ }
426
+ }
427
+ ```
428
+
429
+ ## Contributing
430
+
431
+ We encourage contributions to mac-zoomeye-org to help expand and improve its functionality. Whether it's adding new related tools, enhancing existing features, or improving documentation, your input is valuable.
432
+
433
+ For examples of other MCP servers and implementation patterns, see:
434
+ https://github.com/modelcontextprotocol/servers
435
+
436
+ Pull requests are welcome! Feel free to contribute new ideas, bug fixes, or enhancements to make mac-zoomeye-org more robust and practical.
437
+
438
+ ## License
439
+
440
+ mac-zoomeye-org is licensed under the MIT License. This means you are free to use, modify, and distribute the software, subject to the terms and conditions of the MIT License. For more information, see the LICENSE file in the project repository.
@@ -0,0 +1,8 @@
1
+ mcp_zoomeye_org/__init__.py,sha256=M9-z6h2rrMvPUTCtAw0j_iGphrD8KiFQXylwBfa0qj8,440
2
+ mcp_zoomeye_org/__main__.py,sha256=DSxm3VDrBM5-hCe_ccFSbTu2jgVO64XuWJxLDR9iBFU,40
3
+ mcp_zoomeye_org/prompts.py,sha256=swFBgG77S9n1OMIUyuSyWDRWSmnuG3ZE24e5r1Rp26w,10308
4
+ mcp_zoomeye_org/server.py,sha256=V5umTNmAAERVWEfz7qlP8aKphzD36j1nj0jYUIs0CCE,10759
5
+ mcp_zoomeye_org-0.1.0.dist-info/METADATA,sha256=jAc7iufy5F43CS7Yg0cu6F5GRvcY6a2bubWub3v2Ft0,12950
6
+ mcp_zoomeye_org-0.1.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
7
+ mcp_zoomeye_org-0.1.0.dist-info/entry_points.txt,sha256=g8ocdd0a8JWOz6QbOTbFOKXKkDRppzfp3cxpNtNpjfI,57
8
+ mcp_zoomeye_org-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.27.0
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ mcp-zoomeye-org = mcp_zoomeye_org:main