mirror of
https://github.com/prowler-cloud/prowler.git
synced 2025-12-19 05:17:47 +00:00
fix: MCP findings tools errors (#9477)
This commit is contained in:
committed by
GitHub
parent
45cc6e8b85
commit
20ed8b3d2d
@@ -19,12 +19,17 @@ class CheckRemediation(MinimalSerializerMixin, BaseModel):
|
||||
default=None,
|
||||
description="Terraform code snippet with best practices for remediation",
|
||||
)
|
||||
recommendation_text: str | None = Field(
|
||||
default=None, description="Text description with best practices"
|
||||
)
|
||||
recommendation_url: str | None = Field(
|
||||
nativeiac: str | None = Field(
|
||||
default=None,
|
||||
description="URL to external remediation documentation",
|
||||
description="Native Infrastructure as Code code snippet with best practices for remediation",
|
||||
)
|
||||
other: str | None = Field(
|
||||
default=None,
|
||||
description="Other remediation code snippet with best practices for remediation, usually used for web interfaces or other tools",
|
||||
)
|
||||
recommendation: str | None = Field(
|
||||
default=None,
|
||||
description="Text description with general best recommended practices to avoid the issue",
|
||||
)
|
||||
|
||||
|
||||
@@ -33,9 +38,6 @@ class CheckMetadata(MinimalSerializerMixin, BaseModel):
|
||||
|
||||
model_config = ConfigDict(frozen=True)
|
||||
|
||||
check_id: str = Field(
|
||||
description="Unique provider identifier for the security check (e.g., 's3_bucket_public_access')",
|
||||
)
|
||||
title: str = Field(
|
||||
description="Human-readable title of the security check",
|
||||
)
|
||||
@@ -59,9 +61,9 @@ class CheckMetadata(MinimalSerializerMixin, BaseModel):
|
||||
default=None,
|
||||
description="Remediation guidance including CLI commands and recommendations",
|
||||
)
|
||||
related_url: str | None = Field(
|
||||
default=None,
|
||||
description="URL to additional documentation or references",
|
||||
additional_urls: list[str] = Field(
|
||||
default_factory=list,
|
||||
description="List of additional URLs related to the check",
|
||||
)
|
||||
categories: list[str] = Field(
|
||||
default_factory=list,
|
||||
@@ -79,23 +81,23 @@ class CheckMetadata(MinimalSerializerMixin, BaseModel):
|
||||
recommendation = remediation_data.get("recommendation", {})
|
||||
|
||||
remediation = CheckRemediation(
|
||||
cli=code.get("cli"),
|
||||
terraform=code.get("terraform"),
|
||||
recommendation_text=recommendation.get("text"),
|
||||
recommendation_url=recommendation.get("url"),
|
||||
cli=code["cli"],
|
||||
terraform=code["terraform"],
|
||||
nativeiac=code["nativeiac"],
|
||||
other=code["other"],
|
||||
recommendation=recommendation["text"],
|
||||
)
|
||||
|
||||
return cls(
|
||||
check_id=data["checkid"],
|
||||
title=data["checktitle"],
|
||||
description=data["description"],
|
||||
provider=data["provider"],
|
||||
risk=data.get("risk"),
|
||||
risk=data["risk"],
|
||||
service=data["servicename"],
|
||||
resource_type=data["resourcetype"],
|
||||
remediation=remediation,
|
||||
related_url=data.get("relatedurl"),
|
||||
categories=data.get("categories", []),
|
||||
additional_urls=data["additionalurls"],
|
||||
categories=data["categories"],
|
||||
)
|
||||
|
||||
|
||||
@@ -116,35 +118,36 @@ class SimplifiedFinding(MinimalSerializerMixin, BaseModel):
|
||||
severity: Literal["critical", "high", "medium", "low", "informational"] = Field(
|
||||
description="Severity level of the finding",
|
||||
)
|
||||
check_metadata: CheckMetadata = Field(
|
||||
description="Metadata about the security check that generated this finding",
|
||||
check_id: str = Field(
|
||||
description="ID of the security check that generated this finding",
|
||||
)
|
||||
status_extended: str = Field(
|
||||
description="Extended status information providing additional context",
|
||||
)
|
||||
delta: Literal["new", "changed"] = Field(
|
||||
delta: Literal["new", "changed"] | None = Field(
|
||||
default=None,
|
||||
description="Change status: 'new' (not seen before), 'changed' (modified since last scan), or None (unchanged)",
|
||||
)
|
||||
muted: bool = Field(
|
||||
muted: bool | None = Field(
|
||||
default=None,
|
||||
description="Whether this finding has been muted/suppressed by the user",
|
||||
)
|
||||
muted_reason: str = Field(
|
||||
muted_reason: str | None = Field(
|
||||
default=None,
|
||||
description="Reason provided when muting this finding (3-500 chars if muted)",
|
||||
description="Reason provided when muting this finding",
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def from_api_response(cls, data: dict) -> "SimplifiedFinding":
|
||||
"""Transform JSON:API finding response to simplified format."""
|
||||
attributes = data["attributes"]
|
||||
check_metadata = attributes["check_metadata"]
|
||||
|
||||
return cls(
|
||||
id=data["id"],
|
||||
uid=attributes["uid"],
|
||||
status=attributes["status"],
|
||||
severity=attributes["severity"],
|
||||
check_metadata=CheckMetadata.from_api_response(check_metadata),
|
||||
check_id=attributes["check_metadata"]["checkid"],
|
||||
status_extended=attributes["status_extended"],
|
||||
delta=attributes["delta"],
|
||||
muted=attributes["muted"],
|
||||
@@ -179,6 +182,9 @@ class DetailedFinding(SimplifiedFinding):
|
||||
default_factory=list,
|
||||
description="List of UUIDs for cloud resources associated with this finding",
|
||||
)
|
||||
check_metadata: CheckMetadata = Field(
|
||||
description="Metadata about the security check that generated this finding",
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def from_api_response(cls, data: dict) -> "DetailedFinding":
|
||||
@@ -204,6 +210,7 @@ class DetailedFinding(SimplifiedFinding):
|
||||
uid=attributes["uid"],
|
||||
status=attributes["status"],
|
||||
severity=attributes["severity"],
|
||||
check_id=check_metadata["checkid"],
|
||||
check_metadata=CheckMetadata.from_api_response(check_metadata),
|
||||
status_extended=attributes.get("status_extended"),
|
||||
delta=attributes.get("delta"),
|
||||
|
||||
@@ -19,9 +19,9 @@ class FindingsTools(BaseTool):
|
||||
"""Tools for security findings operations.
|
||||
|
||||
Provides tools for:
|
||||
- Searching and filtering security findings
|
||||
- Getting detailed finding information
|
||||
- Viewing findings overview/statistics
|
||||
- search_security_findings: Fast and lightweight searching across findings
|
||||
- get_finding_details: Get complete details for a specific finding
|
||||
- get_findings_overview: Get aggregate statistics and trends across all findings
|
||||
"""
|
||||
|
||||
async def search_security_findings(
|
||||
@@ -90,27 +90,27 @@ class FindingsTools(BaseTool):
|
||||
) -> dict[str, Any]:
|
||||
"""Search and filter security findings across all cloud providers with rich filtering capabilities.
|
||||
|
||||
This is the primary tool for browsing and filtering security findings. Returns lightweight findings
|
||||
optimized for searching across large result sets. For detailed information about a specific finding,
|
||||
use get_finding_details.
|
||||
IMPORTANT: This tool returns LIGHTWEIGHT findings. Use this for fast searching and filtering across many findings.
|
||||
For complete details use prowler_app_get_finding_details on specific findings.
|
||||
|
||||
Default behavior:
|
||||
- Returns latest findings from most recent scans (no date parameters needed)
|
||||
- Filters to FAIL status only (security issues found)
|
||||
- Returns 100 results per page
|
||||
- Returns 50 results per page
|
||||
|
||||
Date filtering:
|
||||
- Without dates: queries findings from the most recent completed scan across all providers (most efficient). This returns the latest snapshot of findings, not a time-based query.
|
||||
- With dates: queries historical findings (2-day maximum range)
|
||||
- Without dates: queries findings from the most recent completed scan across all providers (most efficient)
|
||||
- With dates: queries historical findings (2-day maximum range between date_from and date_to)
|
||||
|
||||
Each finding includes:
|
||||
- Core identification: id, uid, check_id
|
||||
- Security context: status, severity, check_metadata (title, description, remediation)
|
||||
- State tracking: delta (new/changed), muted status
|
||||
- Extended details: status_extended for additional context
|
||||
- Core identification: id (UUID for get_finding_details), uid, check_id
|
||||
- Security context: status (FAIL/PASS/MANUAL), severity (critical/high/medium/low/informational)
|
||||
- State tracking: delta (new/changed/unchanged), muted (boolean), muted_reason
|
||||
- Extended details: status_extended with additional context
|
||||
|
||||
Returns:
|
||||
Paginated list of simplified findings with total count and pagination metadata
|
||||
Workflow:
|
||||
1. Use this tool to search and filter findings by severity, status, provider, service, region, etc.
|
||||
2. Use prowler_app_get_finding_details with the finding 'id' to get complete information about the finding
|
||||
"""
|
||||
# Validate page_size parameter
|
||||
self.api_client.validate_page_size(page_size)
|
||||
@@ -185,21 +185,39 @@ class FindingsTools(BaseTool):
|
||||
) -> dict[str, Any]:
|
||||
"""Retrieve comprehensive details about a specific security finding by its ID.
|
||||
|
||||
This tool provides MORE detailed information than search_security_findings. Use this when you need
|
||||
to deeply analyze a specific finding or understand its complete context and history.
|
||||
IMPORTANT: This tool returns COMPLETE finding details.
|
||||
Use this after finding a specific finding via prowler_app_search_security_findings
|
||||
|
||||
Additional information compared to search_security_findings:
|
||||
- Temporal metadata: when the finding was first seen, inserted, and last updated
|
||||
- Scan relationship: ID of the scan that generated this finding
|
||||
- Resource relationships: IDs of all cloud resources associated with this finding
|
||||
This tool provides ALL information that prowler_app_search_security_findings returns PLUS:
|
||||
|
||||
1. Check Metadata (information about the check script that generated the finding):
|
||||
- title: Human-readable phrase used to summarize the check
|
||||
- description: Detailed explanation of what the check validates and why it is important
|
||||
- risk: What could happen if this check fails
|
||||
- remediation: Complete remediation guidance including step-by-step instructions and code snippets with best practices to fix the issue:
|
||||
* cli: Command-line commands to fix the issue
|
||||
* terraform: Terraform code snippets with best practices
|
||||
* nativeiac: Provider native Infrastructure as Code code snippets with best practices to fix the issue
|
||||
* other: Other remediation code snippets with best practices, usually used for web interfaces or other tools
|
||||
* recommendation: Text description with general best recommended practices to avoid the issue
|
||||
- provider: Cloud provider (aws/azure/gcp/etc)
|
||||
- service: Service name (s3/ec2/keyvault/etc)
|
||||
- resource_type: Resource type being evaluated
|
||||
- categories: Security categories this check belongs to
|
||||
- additional_urls: List of additional URLs related to the check
|
||||
|
||||
2. Temporal Metadata:
|
||||
- inserted_at: When this finding was first inserted into database
|
||||
- updated_at: When this finding was last updated
|
||||
- first_seen_at: When this finding was first detected across all scans
|
||||
|
||||
3. Relationships:
|
||||
- scan_id: UUID of the scan that generated this finding
|
||||
- resource_ids: List of UUIDs for cloud resources associated with this finding
|
||||
|
||||
Workflow:
|
||||
1. Use search_security_findings to browse and filter across many findings
|
||||
2. Use get_finding_details to drill down into specific findings of interest
|
||||
|
||||
Returns:
|
||||
dict containing detailed finding with comprehensive security metadata, temporal information,
|
||||
and relationships to scans and resources
|
||||
1. Use prowler_app_search_security_findings to browse and filter findings
|
||||
2. Use this tool with the finding 'id' to get remediation guidance and complete context
|
||||
"""
|
||||
params = {
|
||||
# Return comprehensive fields including temporal metadata
|
||||
@@ -225,26 +243,31 @@ class FindingsTools(BaseTool):
|
||||
description="Filter statistics by cloud provider. Multiple values allowed. If empty, all providers are returned. For valid values, please refer to Prowler Hub/Prowler Documentation that you can also find in form of tools in this MCP Server.",
|
||||
),
|
||||
) -> dict[str, Any]:
|
||||
"""Get high-level statistics about security findings formatted as a human-readable markdown report.
|
||||
"""Get aggregate statistics and trends about security findings as a markdown report.
|
||||
|
||||
Use this tool to get a quick overview of your security posture without retrieving individual findings.
|
||||
Perfect for understanding trends, identifying areas of concern, and tracking improvements over time.
|
||||
This tool provides a HIGH-LEVEL OVERVIEW without retrieving individual findings. Use this when you
|
||||
need to understand the overall security posture, trends, or remediation progress across all findings.
|
||||
|
||||
The report includes:
|
||||
- Summary statistics: total findings, fail/pass/muted counts with percentages
|
||||
- Delta analysis: breakdown of new vs changed findings
|
||||
- Trending information: how findings are evolving over time
|
||||
The markdown report includes:
|
||||
|
||||
Output format: Markdown-formatted report ready to present to users or include in documentation.
|
||||
1. Summary Statistics:
|
||||
- Total number of findings
|
||||
- Failed checks (security issues) with percentage
|
||||
- Passed checks (no issues) with percentage
|
||||
- Muted findings (user-suppressed) with percentage
|
||||
|
||||
Use cases:
|
||||
- Quick security posture assessment
|
||||
- Tracking remediation progress over time
|
||||
- Identifying which providers have most issues
|
||||
- Understanding finding trends (improving or degrading)
|
||||
2. Delta Analysis (Change Tracking):
|
||||
- New findings: never seen before in previous scans
|
||||
* Broken down by: new failures, new passes, new muted
|
||||
- Changed findings: status changed since last scan
|
||||
* Broken down by: changed to fail, changed to pass, changed to muted
|
||||
- Unchanged findings: same status as previous scan
|
||||
|
||||
Returns:
|
||||
Dictionary with 'report' key containing markdown-formatted summary statistics
|
||||
This helps answer questions like:
|
||||
- "What's my overall security posture?"
|
||||
- "How many critical security issues do I have?"
|
||||
- "Are we improving or getting worse over time?"
|
||||
- "How many new security issues appeared since last scan?"
|
||||
"""
|
||||
params = {
|
||||
# Return only LLM-relevant aggregate statistics
|
||||
|
||||
Reference in New Issue
Block a user