feat: add comprehensive security, license, health, and requirements analysis tools
- Add security vulnerability scanning with OSV and GitHub advisories integration - Add license compatibility analysis with SPDX normalization and risk assessment - Add package health scoring across 7 categories with GitHub metrics integration - Add requirements file analysis supporting multiple formats (requirements.txt, pyproject.toml, etc.) - Fix search functionality MCP wrapper and error handling - Fix Python compatibility checking parameter order issue - Fix package recommendations NoneType handling - Add 8 new MCP tool endpoints for enhanced analysis capabilities This brings the total to 37 comprehensive MCP tools across 8 categories for complete PyPI package analysis and management.
This commit is contained in:
parent
48f1027c3e
commit
43f36b60fb
12 changed files with 4688 additions and 53 deletions
147
pypi_query_mcp/tools/security_tools.py
Normal file
147
pypi_query_mcp/tools/security_tools.py
Normal file
|
|
@ -0,0 +1,147 @@
|
|||
"""Security vulnerability scanning tools for PyPI packages."""
|
||||
|
||||
import logging
|
||||
from typing import Any, Dict, List, Optional
|
||||
|
||||
from ..core.exceptions import InvalidPackageNameError, NetworkError, SearchError
|
||||
from ..tools.security import bulk_security_scan, scan_package_security
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
async def scan_pypi_package_security(
|
||||
package_name: str,
|
||||
version: Optional[str] = None,
|
||||
include_dependencies: bool = True,
|
||||
severity_filter: Optional[str] = None
|
||||
) -> Dict[str, Any]:
|
||||
"""
|
||||
Scan a PyPI package for security vulnerabilities.
|
||||
|
||||
This tool performs comprehensive security vulnerability scanning of PyPI packages,
|
||||
checking against multiple vulnerability databases including OSV (Open Source Vulnerabilities),
|
||||
GitHub Security Advisories, and analyzing package metadata for security indicators.
|
||||
|
||||
Args:
|
||||
package_name: Name of the package to scan for vulnerabilities
|
||||
version: Specific version to scan (optional, defaults to latest version)
|
||||
include_dependencies: Whether to scan package dependencies for vulnerabilities
|
||||
severity_filter: Filter results by severity level (low, medium, high, critical)
|
||||
|
||||
Returns:
|
||||
Dictionary containing comprehensive security scan results including:
|
||||
- Total vulnerability count and severity breakdown
|
||||
- Direct package vulnerabilities vs dependency vulnerabilities
|
||||
- Risk score and level assessment (minimal, low, medium, high, critical)
|
||||
- Detailed vulnerability information with IDs, descriptions, and references
|
||||
- Package metadata security analysis
|
||||
- Actionable security recommendations
|
||||
|
||||
Raises:
|
||||
InvalidPackageNameError: If package name is empty or invalid
|
||||
PackageNotFoundError: If package is not found on PyPI
|
||||
NetworkError: For network-related errors
|
||||
SearchError: If security scanning fails
|
||||
"""
|
||||
if not package_name or not package_name.strip():
|
||||
raise InvalidPackageNameError(package_name)
|
||||
|
||||
logger.info(f"MCP tool: Scanning security for package {package_name}")
|
||||
|
||||
try:
|
||||
result = await scan_package_security(
|
||||
package_name=package_name,
|
||||
version=version,
|
||||
include_dependencies=include_dependencies,
|
||||
severity_filter=severity_filter
|
||||
)
|
||||
|
||||
logger.info(f"MCP tool: Security scan completed for {package_name} - found {result.get('security_summary', {}).get('total_vulnerabilities', 0)} vulnerabilities")
|
||||
return result
|
||||
|
||||
except (InvalidPackageNameError, NetworkError, SearchError) as e:
|
||||
logger.error(f"Error scanning security for {package_name}: {e}")
|
||||
return {
|
||||
"error": f"Security scan failed: {e}",
|
||||
"error_type": type(e).__name__,
|
||||
"package": package_name,
|
||||
"version": version,
|
||||
"scan_timestamp": "",
|
||||
"security_summary": {
|
||||
"total_vulnerabilities": 0,
|
||||
"direct_vulnerabilities": 0,
|
||||
"dependency_vulnerabilities": 0,
|
||||
"severity_breakdown": {"critical": 0, "high": 0, "medium": 0, "low": 0, "unknown": 0},
|
||||
"risk_score": 0,
|
||||
"risk_level": "unknown",
|
||||
},
|
||||
"vulnerabilities": {"direct": [], "dependencies": []},
|
||||
"metadata_analysis": {},
|
||||
"recommendations": [f"❌ Security scan failed: {e}"],
|
||||
"scan_details": {
|
||||
"sources_checked": [],
|
||||
"dependencies_scanned": False,
|
||||
"scan_completion": "error",
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
async def bulk_scan_package_security(
|
||||
package_names: List[str],
|
||||
include_dependencies: bool = False,
|
||||
severity_threshold: str = "medium"
|
||||
) -> Dict[str, Any]:
|
||||
"""
|
||||
Perform bulk security scanning of multiple PyPI packages.
|
||||
|
||||
This tool scans multiple packages simultaneously for security vulnerabilities,
|
||||
providing a consolidated report with summary statistics and prioritized
|
||||
recommendations for addressing security issues across your package ecosystem.
|
||||
|
||||
Args:
|
||||
package_names: List of package names to scan for vulnerabilities
|
||||
include_dependencies: Whether to include dependency vulnerability scanning
|
||||
severity_threshold: Minimum severity level to report (low, medium, high, critical)
|
||||
|
||||
Returns:
|
||||
Dictionary containing bulk scan results including:
|
||||
- Summary statistics (total packages, packages with vulnerabilities, high-risk packages)
|
||||
- Detailed scan results for each package
|
||||
- Prioritized recommendations for security remediation
|
||||
- Scan timestamp and completion status
|
||||
|
||||
Raises:
|
||||
ValueError: If package_names list is empty
|
||||
NetworkError: For network-related errors during scanning
|
||||
SearchError: If bulk scanning fails
|
||||
"""
|
||||
if not package_names:
|
||||
raise ValueError("Package names list cannot be empty")
|
||||
|
||||
logger.info(f"MCP tool: Starting bulk security scan of {len(package_names)} packages")
|
||||
|
||||
try:
|
||||
result = await bulk_security_scan(
|
||||
package_names=package_names,
|
||||
include_dependencies=include_dependencies,
|
||||
severity_threshold=severity_threshold
|
||||
)
|
||||
|
||||
logger.info(f"MCP tool: Bulk security scan completed - {result.get('summary', {}).get('packages_with_vulnerabilities', 0)} packages have vulnerabilities")
|
||||
return result
|
||||
|
||||
except (ValueError, NetworkError, SearchError) as e:
|
||||
logger.error(f"Error in bulk security scan: {e}")
|
||||
return {
|
||||
"error": f"Bulk security scan failed: {e}",
|
||||
"error_type": type(e).__name__,
|
||||
"summary": {
|
||||
"total_packages": len(package_names),
|
||||
"packages_with_vulnerabilities": 0,
|
||||
"total_vulnerabilities": 0,
|
||||
"high_risk_packages": [],
|
||||
"scan_timestamp": ""
|
||||
},
|
||||
"detailed_results": {},
|
||||
"recommendations": [f"❌ Bulk security scan failed: {e}"]
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue