Skip to main content
Glama

cves_by_product

Search for vulnerabilities affecting specific products or CPEs. Filter by KEV status, sort by EPSS score, and retrieve detailed vulnerability information with severity assessments.

Instructions

Search for vulnerabilities affecting specific products or CPEs. Supports filtering by KEV status, sorting by EPSS score, date ranges, and pagination. Can search by product name or CPE 2.3 identifier. Returns detailed vulnerability information including severity scores and impact assessments.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
cpe23NoThe CPE version 2.3 identifier (format: cpe:2.3:part:vendor:product:version).
productNoThe name of the product to search for CVEs.
countNoIf true, returns only the count of matching CVEs.
is_kevNoIf true, returns only CVEs with the KEV flag set.
sort_by_epssNoIf true, sorts CVEs by EPSS score in descending order.
skipNoNumber of CVEs to skip (for pagination).
limitNoMaximum number of CVEs to return (max 1000).
start_dateNoStart date for filtering CVEs (format: YYYY-MM-DDTHH:MM:SS).
end_dateNoEnd date for filtering CVEs (format: YYYY-MM-DDTHH:MM:SS).

Implementation Reference

  • Main execution handler for the 'cves_by_product' tool within the CallToolRequestSchema handler. Parses arguments, calls the helper function, formats the CVE data with severity assessments, and returns structured JSON response or error.
    case "cves_by_product": { const parsedArgs = CVEsByProductArgsSchema.safeParse(args); if (!parsedArgs.success) { throw new Error("Invalid arguments. Must provide either cpe23 or product name, but not both."); } try { const result = await queryCVEsByProduct({ cpe23: parsedArgs.data.cpe23, product: parsedArgs.data.product, count: parsedArgs.data.count, is_kev: parsedArgs.data.is_kev, sort_by_epss: parsedArgs.data.sort_by_epss, skip: parsedArgs.data.skip, limit: parsedArgs.data.limit, start_date: parsedArgs.data.start_date, end_date: parsedArgs.data.end_date }); // Helper function to format CVSS score severity const getCvssSeverity = (score: number) => { if (score >= 9.0) return "Critical"; if (score >= 7.0) return "High"; if (score >= 4.0) return "Medium"; if (score >= 0.1) return "Low"; return "None"; }; // Format the response based on whether it's a count request or full CVE list const formattedResult = parsedArgs.data.count ? { "Query Information": { "Product": parsedArgs.data.product || "N/A", "CPE 2.3": parsedArgs.data.cpe23 || "N/A", "KEV Only": parsedArgs.data.is_kev ? "Yes" : "No", "Sort by EPSS": parsedArgs.data.sort_by_epss ? "Yes" : "No" }, "Results": { "Total CVEs Found": result.total } } : { "Query Information": { "Product": parsedArgs.data.product || "N/A", "CPE 2.3": parsedArgs.data.cpe23 || "N/A", "KEV Only": parsedArgs.data.is_kev ? "Yes" : "No", "Sort by EPSS": parsedArgs.data.sort_by_epss ? "Yes" : "No", "Date Range": parsedArgs.data.start_date ? `${parsedArgs.data.start_date} to ${parsedArgs.data.end_date || 'now'}` : "All dates" }, "Results Summary": { "Total CVEs Found": result.total, "CVEs Returned": result.cves.length, "Page": `${Math.floor(parsedArgs.data.skip! / parsedArgs.data.limit!) + 1}`, "CVEs per Page": parsedArgs.data.limit }, "Vulnerabilities": result.cves.map((cve: CveResponse) => ({ "Basic Information": { "CVE ID": cve.cve_id, "Published": new Date(cve.published_time).toLocaleString(), "Summary": cve.summary }, "Severity Scores": { "CVSS v3": cve.cvss_v3 ? { "Score": cve.cvss_v3, "Severity": getCvssSeverity(cve.cvss_v3) } : "Not available", "CVSS v2": cve.cvss_v2 ? { "Score": cve.cvss_v2, "Severity": getCvssSeverity(cve.cvss_v2) } : "Not available", "EPSS": cve.epss ? { "Score": `${(cve.epss * 100).toFixed(2)}%`, "Ranking": `Top ${(cve.ranking_epss * 100).toFixed(2)}%` } : "Not available" }, "Impact Assessment": { "Known Exploited Vulnerability": cve.kev ? "Yes" : "No", "Proposed Action": cve.propose_action || "No specific action proposed", "Ransomware Campaign": cve.ransomware_campaign || "No known ransomware campaigns" }, "References": cve.references?.length > 0 ? cve.references : ["No references provided"] })) }; return { content: [ { type: "text", text: JSON.stringify(formattedResult, null, 2), }, ], }; } catch (error: any) { return { content: [ { type: "text", text: error.message, }, ], isError: true, }; } }
  • Core helper function that performs the HTTP request to Shodan's CVEDB API (/cves endpoint) to fetch CVEs by product or CPE, handling errors appropriately.
    // Helper Function for CVEs by product/CPE lookups using CVEDB async function queryCVEsByProduct(params: { cpe23?: string; product?: string; count?: boolean; is_kev?: boolean; sort_by_epss?: boolean; skip?: number; limit?: number; start_date?: string; end_date?: string; }) { try { logToFile(`Querying CVEDB for CVEs with params: ${JSON.stringify(params)}`); const response = await axios.get(`${CVEDB_API_URL}/cves`, { params }); return response.data; } catch (error: any) { if (error.response?.status === 422) { throw new Error(`Invalid parameters: ${error.response.data?.detail || error.message}`); } throw new Error(`CVEDB API error: ${error.message}`); } }
  • Zod schema defining and validating the input parameters for the cves_by_product tool, with refinements ensuring exactly one of cpe23 or product is provided.
    const CVEsByProductArgsSchema = z.object({ cpe23: z.string().optional().describe("The CPE version 2.3 identifier (format: cpe:2.3:part:vendor:product:version)."), product: z.string().optional().describe("The name of the product to search for CVEs."), count: z.boolean().optional().default(false).describe("If true, returns only the count of matching CVEs."), is_kev: z.boolean().optional().default(false).describe("If true, returns only CVEs with the KEV flag set."), sort_by_epss: z.boolean().optional().default(false).describe("If true, sorts CVEs by EPSS score in descending order."), skip: z.number().optional().default(0).describe("Number of CVEs to skip (for pagination)."), limit: z.number().optional().default(1000).describe("Maximum number of CVEs to return (max 1000)."), start_date: z.string().optional().describe("Start date for filtering CVEs (format: YYYY-MM-DDTHH:MM:SS)."), end_date: z.string().optional().describe("End date for filtering CVEs (format: YYYY-MM-DDTHH:MM:SS).") }).refine( data => !(data.cpe23 && data.product), { message: "Cannot specify both cpe23 and product. Use only one." } ).refine( data => data.cpe23 || data.product, { message: "Must specify either cpe23 or product." } );
  • src/index.ts:341-345 (registration)
    Tool registration in the ListToolsRequestSchema handler, defining the tool name, description, and linking to the input schema.
    { name: "cves_by_product", description: "Search for vulnerabilities affecting specific products or CPEs. Supports filtering by KEV status, sorting by EPSS score, date ranges, and pagination. Can search by product name or CPE 2.3 identifier. Returns detailed vulnerability information including severity scores and impact assessments.", inputSchema: zodToJsonSchema(CVEsByProductArgsSchema), },

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/BurtTheCoder/mcp-shodan'

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