diff --git a/docs/developer-guide/mcp-server.mdx b/docs/developer-guide/mcp-server.mdx
new file mode 100644
index 0000000000..4174f0f730
--- /dev/null
+++ b/docs/developer-guide/mcp-server.mdx
@@ -0,0 +1,447 @@
+---
+title: 'Extending the MCP Server'
+---
+
+This guide explains how to extend the Prowler MCP Server with new tools and features.
+
+
+**New to Prowler MCP Server?** Start with the user documentation:
+- [Overview](/getting-started/products/prowler-mcp) - Key capabilities, use cases, and deployment options
+- [Installation](/getting-started/installation/prowler-mcp) - Install locally or use the managed server
+- [Configuration](/getting-started/basic-usage/prowler-mcp) - Configure Claude Desktop, Cursor, and other MCP hosts
+- [Tools Reference](/getting-started/basic-usage/prowler-mcp-tools) - Complete list of all available tools
+
+
+## Introduction
+
+The Prowler MCP Server brings the entire Prowler ecosystem to AI assistants through the [Model Context Protocol (MCP)](https://modelcontextprotocol.io). It enables seamless integration with AI tools like Claude Desktop, Cursor, and other MCP clients.
+
+The server follows a modular architecture with three independent sub-servers:
+
+| Sub-Server | Auth Required | Description |
+|------------|---------------|-------------|
+| Prowler App | Yes | Full access to Prowler Cloud and Self-Managed features |
+| Prowler Hub | No | Security checks catalog with **over 1000 checks**, fixers, and **70+ compliance frameworks** |
+| Prowler Documentation | No | Full-text search and retrieval of official documentation |
+
+
+For a complete list of tools and their descriptions, see the [Tools Reference](/getting-started/basic-usage/prowler-mcp-tools).
+
+
+## Architecture Overview
+
+The MCP Server architecture is illustrated in the [Overview documentation](/getting-started/products/prowler-mcp#mcp-server-architecture). AI assistants connect through the MCP protocol to access Prowler's three main components.
+
+### Server Structure
+
+The main server orchestrates three sub-servers with prefixed namespacing:
+
+```
+mcp_server/prowler_mcp_server/
+├── server.py # Main orchestrator
+├── main.py # CLI entry point
+├── prowler_hub/
+├── prowler_app/
+│ ├── tools/ # Tool implementations
+│ ├── models/ # Pydantic models
+│ └── utils/ # API client, auth, loader
+└── prowler_documentation/
+```
+
+### Tool Registration Patterns
+
+The MCP Server uses two patterns for tool registration:
+
+1. **Direct Decorators** (Prowler Hub/Docs): Tools are registered using `@mcp.tool()` decorators
+2. **Auto-Discovery** (Prowler App): All public methods of `BaseTool` subclasses are auto-registered
+
+## Adding Tools to Prowler App
+
+### Step 1: Create the Tool Class
+
+Create a new file or add to an existing file in `prowler_app/tools/`:
+
+```python
+# prowler_app/tools/new_feature.py
+from typing import Any
+
+from pydantic import Field
+
+from prowler_mcp_server.prowler_app.models.new_feature import (
+ FeatureListResponse,
+ DetailedFeature,
+)
+from prowler_mcp_server.prowler_app.tools.base import BaseTool
+
+
+class NewFeatureTools(BaseTool):
+ """Tools for managing new features."""
+
+ async def list_features(
+ self,
+ status: str | None = Field(
+ default=None,
+ description="Filter by status (active, inactive, pending)"
+ ),
+ page_size: int = Field(
+ default=50,
+ description="Number of results per page (1-100)"
+ ),
+ ) -> dict[str, Any]:
+ """List all features with optional filtering.
+
+ Returns a lightweight list of features optimized for LLM consumption.
+ Use get_feature for complete information about a specific feature.
+ """
+ # Validate parameters
+ self.api_client.validate_page_size(page_size)
+
+ # Build query parameters
+ params: dict[str, Any] = {"page[size]": page_size}
+ if status:
+ params["filter[status]"] = status
+
+ # Make API request
+ clean_params = self.api_client.build_filter_params(params)
+ response = await self.api_client.get("/api/v1/features", params=clean_params)
+
+ # Transform to LLM-friendly format
+ return FeatureListResponse.from_api_response(response).model_dump()
+
+ async def get_feature(
+ self,
+ feature_id: str = Field(description="The UUID of the feature"),
+ ) -> dict[str, Any]:
+ """Get detailed information about a specific feature.
+
+ Returns complete feature details including configuration and metadata.
+ """
+ try:
+ response = await self.api_client.get(f"/api/v1/features/{feature_id}")
+ return DetailedFeature.from_api_response(response["data"]).model_dump()
+ except Exception as e:
+ self.logger.error(f"Failed to get feature {feature_id}: {e}")
+ return {"error": str(e), "status": "failed"}
+```
+
+### Step 2: Create the Models
+
+Create corresponding models in `prowler_app/models/`:
+
+```python
+# prowler_app/models/new_feature.py
+from typing import Any
+
+from pydantic import Field
+
+from prowler_mcp_server.prowler_app.models.base import MinimalSerializerMixin
+
+
+class SimplifiedFeature(MinimalSerializerMixin):
+ """Lightweight feature for list operations."""
+
+ id: str = Field(description="Unique feature identifier")
+ name: str = Field(description="Feature name")
+ status: str = Field(description="Current status")
+
+ @classmethod
+ def from_api_response(cls, data: dict[str, Any]) -> "SimplifiedFeature":
+ """Transform API response to simplified format."""
+ attributes = data.get("attributes", {})
+ return cls(
+ id=data["id"],
+ name=attributes["name"],
+ status=attributes["status"],
+ )
+
+
+class DetailedFeature(SimplifiedFeature):
+ """Extended feature with complete details."""
+
+ description: str | None = Field(default=None, description="Feature description")
+ configuration: dict[str, Any] | None = Field(default=None, description="Configuration")
+ created_at: str = Field(description="Creation timestamp")
+ updated_at: str = Field(description="Last update timestamp")
+
+ @classmethod
+ def from_api_response(cls, data: dict[str, Any]) -> "DetailedFeature":
+ """Transform API response to detailed format."""
+ attributes = data.get("attributes", {})
+ return cls(
+ id=data["id"],
+ name=attributes["name"],
+ status=attributes["status"],
+ description=attributes.get("description"),
+ configuration=attributes.get("configuration"),
+ created_at=attributes["created_at"],
+ updated_at=attributes["updated_at"],
+ )
+
+
+class FeatureListResponse(MinimalSerializerMixin):
+ """Response wrapper for feature list operations."""
+
+ count: int = Field(description="Total number of features")
+ features: list[SimplifiedFeature] = Field(description="List of features")
+
+ @classmethod
+ def from_api_response(cls, response: dict[str, Any]) -> "FeatureListResponse":
+ """Transform API response to list format."""
+ data = response.get("data", [])
+ features = [SimplifiedFeature.from_api_response(item) for item in data]
+ return cls(count=len(features), features=features)
+```
+
+### Step 3: Verify Auto-Discovery
+
+No manual registration is needed. The `tool_loader.py` automatically discovers and registers all `BaseTool` subclasses. Verify your tool is loaded by checking the server logs:
+
+```
+INFO - Auto-registered 2 tools from NewFeatureTools
+INFO - Loaded and registered: NewFeatureTools
+```
+
+## Adding Tools to Prowler Hub/Docs
+
+For Prowler Hub or Documentation tools, use the `@mcp.tool()` decorator directly:
+
+```python
+# prowler_hub/server.py
+from fastmcp import FastMCP
+
+hub_mcp_server = FastMCP("prowler-hub")
+
+@hub_mcp_server.tool()
+async def get_new_artifact(
+ artifact_id: str,
+) -> dict:
+ """Fetch a specific artifact from Prowler Hub.
+
+ Args:
+ artifact_id: The unique identifier of the artifact
+
+ Returns:
+ Dictionary containing artifact details
+ """
+ response = prowler_hub_client.get(f"/artifact/{artifact_id}")
+ response.raise_for_status()
+ return response.json()
+```
+
+## Model Design Patterns
+
+### MinimalSerializerMixin
+
+All models should use `MinimalSerializerMixin` to optimize responses for LLM consumption:
+
+```python
+from prowler_mcp_server.prowler_app.models.base import MinimalSerializerMixin
+
+class MyModel(MinimalSerializerMixin):
+ """Model that excludes empty values from serialization."""
+ required_field: str
+ optional_field: str | None = None # Excluded if None
+ empty_list: list = [] # Excluded if empty
+```
+
+This mixin automatically excludes:
+- `None` values
+- Empty strings
+- Empty lists
+- Empty dictionaries
+
+### Two-Tier Model Pattern
+
+Use two-tier models for efficient responses:
+
+- **Simplified**: Lightweight models for list operations
+- **Detailed**: Extended models for single-item retrieval
+
+```python
+class SimplifiedItem(MinimalSerializerMixin):
+ """Use for list operations - minimal fields."""
+ id: str
+ name: str
+ status: str
+
+class DetailedItem(SimplifiedItem):
+ """Use for get operations - extends simplified with details."""
+ description: str | None = None
+ configuration: dict | None = None
+ created_at: str
+ updated_at: str
+```
+
+### Factory Method Pattern
+
+Always implement `from_api_response()` for API transformation:
+
+```python
+@classmethod
+def from_api_response(cls, data: dict[str, Any]) -> "MyModel":
+ """Transform API response to model.
+
+ This method handles the JSON:API format used by Prowler API,
+ extracting attributes and relationships as needed.
+ """
+ attributes = data.get("attributes", {})
+ return cls(
+ id=data["id"],
+ name=attributes["name"],
+ # ... map other fields
+ )
+```
+
+## API Client Usage
+
+The `ProwlerAPIClient` is a singleton that handles authentication and HTTP requests:
+
+```python
+class MyTools(BaseTool):
+ async def my_tool(self) -> dict:
+ # GET request
+ response = await self.api_client.get("/api/v1/endpoint", params={"key": "value"})
+
+ # POST request
+ response = await self.api_client.post(
+ "/api/v1/endpoint",
+ json_data={"data": {"type": "items", "attributes": {...}}}
+ )
+
+ # PATCH request
+ response = await self.api_client.patch(
+ f"/api/v1/endpoint/{id}",
+ json_data={"data": {"attributes": {...}}}
+ )
+
+ # DELETE request
+ response = await self.api_client.delete(f"/api/v1/endpoint/{id}")
+```
+
+### Helper Methods
+
+The API client provides useful helper methods:
+
+```python
+# Validate page size (1-1000)
+self.api_client.validate_page_size(page_size)
+
+# Normalize date range with max days limit
+date_range = self.api_client.normalize_date_range(date_from, date_to, max_days=2)
+
+# Build filter parameters (handles type conversion)
+clean_params = self.api_client.build_filter_params({
+ "filter[status]": "active",
+ "filter[severity__in]": ["high", "critical"], # Converts to comma-separated
+ "filter[muted]": True, # Converts to "true"
+})
+
+# Poll async task until completion
+result = await self.api_client.poll_task_until_complete(
+ task_id=task_id,
+ timeout=60,
+ poll_interval=1.0
+)
+```
+
+## Best Practices
+
+### Tool Docstrings
+
+Tool docstrings become description that is going to be read by the LLM. Provide clear usage instructions and common workflows:
+
+```python
+async def search_items(self, status: str = Field(...)) -> dict:
+ """Search items with advanced filtering.
+
+ Returns a lightweight list optimized for LLM consumption.
+ Use get_item for complete details about a specific item.
+
+ Common workflows:
+ - Find critical items: status="critical"
+ - Find recent items: Use date_from parameter
+ """
+```
+
+### Error Handling
+
+Return structured error responses instead of raising exceptions:
+
+```python
+async def get_item(self, item_id: str) -> dict:
+ try:
+ response = await self.api_client.get(f"/api/v1/items/{item_id}")
+ return DetailedItem.from_api_response(response["data"]).model_dump()
+ except Exception as e:
+ self.logger.error(f"Failed to get item {item_id}: {e}")
+ return {"error": str(e), "status": "failed"}
+```
+
+### Parameter Descriptions
+
+Use Pydantic `Field()` with clear descriptions. This also helps LLMs understand
+the purpose of each parameter, so be as descriptive as possible:
+
+```python
+async def list_items(
+ self,
+ severity: list[str] = Field(
+ default=[],
+ description="Filter by severity levels (critical, high, medium, low)"
+ ),
+ status: str | None = Field(
+ default=None,
+ description="Filter by status (PASS, FAIL, MANUAL)"
+ ),
+ page_size: int = Field(
+ default=50,
+ description="Results per page"
+ ),
+) -> dict:
+```
+
+## Development Commands
+
+```bash
+# Navigate to MCP server directory
+cd mcp_server
+
+# Run in STDIO mode (default)
+uv run prowler-mcp
+
+# Run in HTTP mode
+uv run prowler-mcp --transport http --host 0.0.0.0 --port 8000
+
+# Run with environment variables
+PROWLER_APP_API_KEY="pk_xxx" uv run prowler-mcp
+```
+
+For complete installation and deployment options, see:
+- [Installation Guide](/getting-started/installation/prowler-mcp#from-source-development) - Development setup instructions
+- [Configuration Guide](/getting-started/basic-usage/prowler-mcp) - MCP client configuration
+
+For development I recommend to use the [Model Context Protocol Inspector](https://github.com/modelcontextprotocol/inspector) as MCP client to test and debug your tools.
+
+## Related Documentation
+
+
+
+ Key capabilities, use cases, and deployment options
+
+
+ Complete reference of all available tools
+
+
+ Security checks and compliance frameworks catalog
+
+
+ AI-powered security analyst
+
+
+
+## Additional Resources
+
+- [MCP Protocol Specification](https://modelcontextprotocol.io) - Model Context Protocol details
+- [Prowler API Documentation](https://api.prowler.com/api/v1/docs) - API reference
+- [Prowler Hub API](https://hub.prowler.com/api/docs) - Hub API reference
+- [GitHub Repository](https://github.com/prowler-cloud/prowler) - Source code
diff --git a/docs/docs.json b/docs/docs.json
index d45a05158d..09181da5cd 100644
--- a/docs/docs.json
+++ b/docs/docs.json
@@ -19,9 +19,7 @@
"groups": [
{
"group": "Welcome",
- "pages": [
- "introduction"
- ]
+ "pages": ["introduction"]
},
{
"group": "Prowler Cloud",
@@ -51,9 +49,7 @@
},
{
"group": "Prowler Lighthouse AI",
- "pages": [
- "getting-started/products/prowler-lighthouse-ai"
- ]
+ "pages": ["getting-started/products/prowler-lighthouse-ai"]
},
{
"group": "Prowler MCP Server",
@@ -153,9 +149,7 @@
"user-guide/cli/tutorials/quick-inventory",
{
"group": "Tutorials",
- "pages": [
- "user-guide/cli/tutorials/parallel-execution"
- ]
+ "pages": ["user-guide/cli/tutorials/parallel-execution"]
}
]
},
@@ -243,9 +237,7 @@
},
{
"group": "LLM",
- "pages": [
- "user-guide/providers/llm/getting-started-llm"
- ]
+ "pages": ["user-guide/providers/llm/getting-started-llm"]
},
{
"group": "Oracle Cloud Infrastructure",
@@ -258,9 +250,7 @@
},
{
"group": "Compliance",
- "pages": [
- "user-guide/compliance/tutorials/threatscore"
- ]
+ "pages": ["user-guide/compliance/tutorials/threatscore"]
}
]
},
@@ -277,7 +267,8 @@
"developer-guide/outputs",
"developer-guide/integrations",
"developer-guide/security-compliance-framework",
- "developer-guide/lighthouse"
+ "developer-guide/lighthouse",
+ "developer-guide/mcp-server"
]
},
{
@@ -313,21 +304,15 @@
},
{
"tab": "Security",
- "pages": [
- "security"
- ]
+ "pages": ["security"]
},
{
"tab": "Contact Us",
- "pages": [
- "contact"
- ]
+ "pages": ["contact"]
},
{
"tab": "Troubleshooting",
- "pages": [
- "troubleshooting"
- ]
+ "pages": ["troubleshooting"]
},
{
"tab": "About Us",
diff --git a/docs/getting-started/basic-usage/prowler-mcp-tools.mdx b/docs/getting-started/basic-usage/prowler-mcp-tools.mdx
index dc984c9537..6ce8c3c685 100644
--- a/docs/getting-started/basic-usage/prowler-mcp-tools.mdx
+++ b/docs/getting-started/basic-usage/prowler-mcp-tools.mdx
@@ -10,7 +10,7 @@ Complete reference guide for all tools available in the Prowler MCP Server. Tool
|----------|------------|------------------------|
| Prowler Hub | 10 tools | No |
| Prowler Documentation | 2 tools | No |
-| Prowler Cloud/App | 28 tools | Yes |
+| Prowler Cloud/App | 22 tools | Yes |
## Tool Naming Convention
@@ -20,6 +20,66 @@ All tools follow a consistent naming pattern with prefixes:
- `prowler_docs_*` - Prowler documentation search and retrieval
- `prowler_app_*` - Prowler Cloud and App (Self-Managed) management tools
+## Prowler Cloud/App Tools
+
+Manage Prowler Cloud or Prowler App (Self-Managed) features. **Requires authentication.**
+
+
+These tools require a valid API key. See the [Configuration Guide](/getting-started/basic-usage/prowler-mcp) for authentication setup.
+
+
+### Findings Management
+
+Tools for searching, viewing, and analyzing security findings across all cloud providers.
+
+- **`prowler_app_search_security_findings`** - Search and filter security findings with advanced filtering options (severity, status, provider, region, service, check ID, date range, muted status)
+- **`prowler_app_get_finding_details`** - Get comprehensive details about a specific finding including remediation guidance, check metadata, and resource relationships
+- **`prowler_app_get_findings_overview`** - Get aggregate statistics and trends about security findings as a markdown report
+
+### Provider Management
+
+Tools for managing cloud provider connections in Prowler.
+
+- **`prowler_app_search_providers`** - Search and view configured providers with their connection status
+- **`prowler_app_connect_provider`** - Register and connect a provider with credentials for security scanning
+- **`prowler_app_delete_provider`** - Permanently remove a provider from Prowler
+
+### Scan Management
+
+Tools for managing and monitoring security scans.
+
+- **`prowler_app_list_scans`** - List and filter security scans across all providers
+- **`prowler_app_get_scan`** - Get comprehensive details about a specific scan (progress, duration, resource counts)
+- **`prowler_app_trigger_scan`** - Trigger a manual security scan for a provider
+- **`prowler_app_schedule_daily_scan`** - Schedule automated daily scans for continuous monitoring
+- **`prowler_app_update_scan`** - Update scan name for better organization
+
+### Resources Management
+
+Tools for searching, viewing, and analyzing cloud resources discovered by Prowler.
+
+- **`prowler_app_list_resources`** - List and filter cloud resources with advanced filtering options (provider, region, service, resource type, tags)
+- **`prowler_app_get_resource`** - Get comprehensive details about a specific resource including configuration, metadata, and finding relationships
+- **`prowler_app_get_resources_overview`** - Get aggregate statistics about cloud resources as a markdown report
+
+### Muting Management
+
+Tools for managing finding muting, including pattern-based bulk muting (mutelist) and finding-specific mute rules.
+
+#### Mutelist (Pattern-Based Muting)
+
+- **`prowler_app_get_mutelist`** - Retrieve the current mutelist configuration for the tenant
+- **`prowler_app_set_mutelist`** - Create or update the mutelist configuration for pattern-based bulk muting
+- **`prowler_app_delete_mutelist`** - Remove the mutelist configuration from the tenant
+
+#### Mute Rules (Finding-Specific Muting)
+
+- **`prowler_app_list_mute_rules`** - Search and filter mute rules with pagination support
+- **`prowler_app_get_mute_rule`** - Retrieve comprehensive details about a specific mute rule
+- **`prowler_app_create_mute_rule`** - Create a new mute rule to mute specific findings with documentation and audit trail
+- **`prowler_app_update_mute_rule`** - Update a mute rule's name, reason, or enabled status
+- **`prowler_app_delete_mute_rule`** - Delete a mute rule from the system
+
## Prowler Hub Tools
Access Prowler's security check catalog and compliance frameworks. **No authentication required.**
@@ -53,60 +113,6 @@ Search and access official Prowler documentation. **No authentication required.*
- **`prowler_docs_search`** - Search the official Prowler documentation using full-text search
- **`prowler_docs_get_document`** - Retrieve the full markdown content of a specific documentation file
-## Prowler Cloud/App Tools
-
-Manage Prowler Cloud or Prowler App (Self-Managed) features. **Requires authentication.**
-
-
-These tools require a valid API key. See the [Configuration Guide](/getting-started/basic-usage/prowler-mcp) for authentication setup.
-
-
-### Findings Management
-
-- **`prowler_app_list_findings`** - List security findings with advanced filtering
-- **`prowler_app_get_finding`** - Get detailed information about a specific finding
-- **`prowler_app_get_latest_findings`** - Retrieve latest findings from the most recent scans
-- **`prowler_app_get_findings_metadata`** - Get unique metadata values from filtered findings
-- **`prowler_app_get_latest_findings_metadata`** - Get metadata from latest findings across all providers
-
-### Provider Management
-
-- **`prowler_app_list_providers`** - List all providers with filtering options
-- **`prowler_app_create_provider`** - Create a new provider in the current tenant
-- **`prowler_app_get_provider`** - Get detailed information about a specific provider
-- **`prowler_app_update_provider`** - Update provider details (alias, etc.)
-- **`prowler_app_delete_provider`** - Delete a specific provider
-- **`prowler_app_test_provider_connection`** - Test provider connection status
-
-### Provider Secrets Management
-
-- **`prowler_app_list_provider_secrets`** - List all provider secrets with filtering
-- **`prowler_app_add_provider_secret`** - Add or update credentials for a provider
-- **`prowler_app_get_provider_secret`** - Get detailed information about a provider secret
-- **`prowler_app_update_provider_secret`** - Update provider secret details
-- **`prowler_app_delete_provider_secret`** - Delete a provider secret
-
-### Scan Management
-
-- **`prowler_app_list_scans`** - List all scans with filtering options
-- **`prowler_app_create_scan`** - Trigger a manual scan for a specific provider
-- **`prowler_app_get_scan`** - Get detailed information about a specific scan
-- **`prowler_app_update_scan`** - Update scan details
-- **`prowler_app_get_scan_compliance_report`** - Download compliance report as CSV
-- **`prowler_app_get_scan_report`** - Download ZIP file containing complete scan report
-
-### Schedule Management
-
-- **`prowler_app_schedules_daily_scan`** - Create a daily scheduled scan for a provider
-
-### Processor Management
-
-- **`prowler_app_processors_list`** - List all processors with filtering
-- **`prowler_app_processors_create`** - Create a new processor (currently only mute lists supported)
-- **`prowler_app_processors_retrieve`** - Get processor details by ID
-- **`prowler_app_processors_partial_update`** - Update processor configuration
-- **`prowler_app_processors_destroy`** - Delete a processor
-
## Usage Tips
- Use natural language to interact with the tools through your AI assistant
diff --git a/docs/getting-started/products/prowler-mcp.mdx b/docs/getting-started/products/prowler-mcp.mdx
index 94a5466edb..df402f605b 100644
--- a/docs/getting-started/products/prowler-mcp.mdx
+++ b/docs/getting-started/products/prowler-mcp.mdx
@@ -19,12 +19,11 @@ The Prowler MCP Server provides three main integration points:
### 1. Prowler Cloud and Prowler App (Self-Managed)
Full access to Prowler Cloud platform and self-managed Prowler App for:
-- **Provider Management**: Create, configure, and manage cloud providers (AWS, Azure, GCP, etc.).
-- **Scan Orchestration**: Trigger on-demand scans and schedule recurring security assessments.
-- **Findings Analysis**: Query, filter, and analyze security findings across all your cloud environments.
-- **Compliance Reporting**: Generate compliance reports for various frameworks (CIS, PCI-DSS, HIPAA, etc.).
-- **Secrets Management**: Securely manage provider credentials and connection details.
-- **Processor Configuration**: Set up the [Prowler Mutelist](/user-guide/tutorials/prowler-app-mute-findings) to mute findings.
+- **Findings Analysis**: Query, filter, and analyze security findings across all your cloud environments
+- **Provider Management**: Create, configure, and manage your configured Prowler providers (AWS, Azure, GCP, etc.)
+- **Scan Orchestration**: Trigger on-demand scans and schedule recurring security assessments
+- **Resource Inventory**: Search and view detailed information about your audited resources
+- **Muting Management**: Create and manage muting lists/rules to suppress non-relevant findings
### 2. Prowler Hub
@@ -49,7 +48,10 @@ The following diagram illustrates the Prowler MCP Server architecture and its in
-The architecture shows how AI assistants connect through the MCP protocol to access Prowler's three main components: Prowler Cloud/App for security operations, Prowler Hub for security knowledge, and Prowler Documentation for guidance and reference.
+The architecture shows how AI assistants connect through the MCP protocol to access Prowler's three main components:
+- Prowler Cloud/App for security operations
+- Prowler Hub for security knowledge
+- Prowler Documentation for guidance and reference.
## Use Cases
@@ -57,12 +59,12 @@ The Prowler MCP Server enables powerful workflows through AI assistants:
**Security Operations**
- "Show me all critical findings from my AWS production accounts"
-- "What is my compliance status for the PCI standards accross all my AWS accounts according to the latest Prowler scan results?"
-- "Register my new AWS account in Prowler and run an scheduled scan every day"
+- "Register my new AWS account in Prowler and run a scheduled scan every day"
+- "List all muted findings and detect what findgings are muted by a not enough good reason in relation to their severity"
**Security Research**
-- "Explain what the S3 bucket public access check does"
-- "Find all checks related to encryption at rest"
+- "Explain what the S3 bucket public access Prowler check does"
+- "Find all Prowler checks related to encryption at rest"
- "What is the latest version of the CIS that Prowler is covering per provider?"
**Documentation & Learning**
diff --git a/mcp_server/AGENTS.md b/mcp_server/AGENTS.md
new file mode 100644
index 0000000000..fdc1ce5535
--- /dev/null
+++ b/mcp_server/AGENTS.md
@@ -0,0 +1,310 @@
+# Prowler MCP Server - AI Agent Ruleset
+
+**Complete guide for AI agents and developers working on the Prowler MCP Server - the Model Context Protocol server that provides AI agents access to the Prowler ecosystem.**
+
+## Project Overview
+
+The Prowler MCP Server brings the entire Prowler ecosystem to AI assistants through
+the Model Context Protocol (MCP). It enables seamless integration with AI tools
+like Claude Desktop, Cursor, and other MCP hosts, allowing interaction with
+Prowler's security capabilities through natural language.
+
+---
+
+## Critical Rules
+
+### Tool Implementation
+
+- **ALWAYS**: Extend `BaseTool` ABC for new Prowler App tools (auto-registration)
+- **ALWAYS**: Use `@mcp.tool()` decorator for Hub/Docs tools (manual registration)
+- **NEVER**: Manually register BaseTool subclasses (auto-discovered via `load_all_tools()`)
+- **NEVER**: Import tools directly in server.py (tool_loader handles discovery)
+
+### Models
+
+- **ALWAYS**: Use `MinimalSerializerMixin` for LLM-optimized responses
+- **ALWAYS**: Implement `from_api_response()` factory method for API transformations
+- **ALWAYS**: Use two-tier models (Simplified for lists, Detailed for single items)
+- **NEVER**: Return raw API responses (transform to simplified models)
+
+### API Client
+
+- **ALWAYS**: Use singleton `ProwlerAPIClient` via `self.api_client` in tools
+- **ALWAYS**: Use `build_filter_params()` for query parameter normalization
+- **NEVER**: Create new httpx clients in tools (use shared client)
+
+---
+
+## Architecture
+
+### Three Sub-Servers Pattern
+
+The main server (`server.py`) orchestrates three independent sub-servers with prefixed tool namespacing:
+
+```python
+# server.py imports sub-servers with prefixes
+await prowler_mcp_server.import_server(hub_mcp_server, prefix="prowler_hub")
+await prowler_mcp_server.import_server(app_mcp_server, prefix="prowler_app")
+await prowler_mcp_server.import_server(docs_mcp_server, prefix="prowler_docs")
+```
+
+This pattern ensures:
+- Failures in one sub-server do not block others
+- Clear tool namespacing for LLM disambiguation
+- Independent development and testing
+
+### Tool Naming Convention
+
+All tools follow a consistent naming pattern with prefixes:
+- `prowler_hub_*` - Prowler Hub catalog and compliance tools
+- `prowler_docs_*` - Prowler documentation search and retrieval
+- `prowler_app_*` - Prowler Cloud and App (Self-Managed) management tools
+
+### Tool Registration Patterns
+
+**Pattern 1: Prowler Hub/Docs (Direct Decorators)**
+
+```python
+# prowler_hub/server.py or prowler_documentation/server.py
+hub_mcp_server = FastMCP("prowler-hub")
+
+@hub_mcp_server.tool()
+async def get_checks(providers: str | None = None) -> dict:
+ """Tool docstring becomes LLM description."""
+ # Direct implementation
+ response = prowler_hub_client.get("/check", params=params)
+ return response.json()
+```
+
+**Pattern 2: Prowler App (BaseTool Auto-Registration)**
+
+```python
+# prowler_app/tools/findings.py
+class FindingsTools(BaseTool):
+ async def search_security_findings(
+ self,
+ severity: list[str] = Field(default=[], description="Filter by severity")
+ ) -> dict:
+ """Docstring becomes LLM description."""
+ response = await self.api_client.get("/api/v1/findings")
+ return SimplifiedFinding.from_api_response(response).model_dump()
+```
+
+NOTE: Only public methods of `BaseTool` subclasses are registered as tools.
+
+---
+
+## Tech Stack
+
+- **Language**: Python 3.12+
+- **MCP Framework**: FastMCP 2.13.1
+- **HTTP Client**: httpx (async)
+- **Validation**: Pydantic with MinimalSerializerMixin
+- **Package Manager**: uv
+
+---
+
+## Project Structure
+
+```
+mcp_server/
+├── README.md # User documentation
+├── AGENTS.md # This file - AI agent guidelines
+├── CHANGELOG.md # Version history
+├── pyproject.toml # Project metadata and dependencies
+├── Dockerfile # Container image definition
+├── entrypoint.sh # Docker entrypoint script
+└── prowler_mcp_server/
+ ├── __init__.py # Version info
+ ├── main.py # CLI entry point
+ ├── server.py # Main FastMCP server orchestration
+ ├── lib/
+ │ └── logger.py # Structured logging
+ ├── prowler_hub/
+ │ └── server.py # Hub tools (10 tools, no auth)
+ ├── prowler_app/
+ │ ├── server.py # App server initialization
+ │ ├── tools/
+ │ │ ├── base.py # BaseTool abstract class
+ │ │ ├── findings.py # Findings tools
+ │ │ ├── providers.py # Provider tools
+ │ │ ├── scans.py # Scan tools
+ │ │ ├── resources.py # Resource tools
+ │ │ └── muting.py # Muting tools
+ │ ├── models/
+ │ │ ├── base.py # MinimalSerializerMixin
+ │ │ ├── findings.py # Finding models
+ │ │ ├── providers.py # Provider models
+ │ │ ├── scans.py # Scan models
+ │ │ ├── resources.py # Resource models
+ │ │ └── muting.py # Muting models
+ │ └── utils/
+ │ ├── api_client.py # ProwlerAPIClient singleton
+ │ ├── auth.py # ProwlerAppAuth (STDIO/HTTP)
+ │ └── tool_loader.py # Auto-discovery and registration
+ └── prowler_documentation/
+ ├── server.py # Documentation tools (2 tools, no auth)
+ └── search_engine.py # Mintlify API integration
+```
+
+---
+
+## Commands
+
+NOTE: To run a python command always use `uv run ` from within the `mcp_server/` directory.
+
+### Development
+
+```bash
+# Navigate to MCP server directory
+cd mcp_server
+
+# Run in STDIO mode (default)
+uv run prowler-mcp
+
+# Run in HTTP mode
+uv run prowler-mcp --transport http --host 0.0.0.0 --port 8000
+
+# Run from anywhere using uvx
+uvx /path/to/prowler/mcp_server/
+```
+
+---
+
+## Development Patterns
+
+### Adding New Tools to Prowler App
+
+1. **Create or extend a tool class** in `prowler_app/tools/`:
+
+```python
+# prowler_app/tools/new_feature.py
+from pydantic import Field
+from prowler_mcp_server.prowler_app.tools.base import BaseTool
+from prowler_mcp_server.prowler_app.models.new_feature import FeatureResponse
+
+class NewFeatureTools(BaseTool):
+ async def list_features(
+ self,
+ status: str | None = Field(default=None, description="Filter by status")
+ ) -> dict:
+ """List all features with optional filtering.
+
+ Returns a simplified list of features optimized for LLM consumption.
+ """
+ params = {}
+ if status:
+ params["filter[status]"] = status
+
+ clean_params = self.api_client.build_filter_params(params)
+ response = await self.api_client.get("/api/v1/features", params=clean_params)
+
+ return FeatureResponse.from_api_response(response).model_dump()
+```
+
+2. **Create corresponding models** in `prowler_app/models/`:
+
+```python
+# prowler_app/models/new_feature.py
+from pydantic import Field
+from prowler_mcp_server.prowler_app.models.base import MinimalSerializerMixin
+
+class SimplifiedFeature(MinimalSerializerMixin):
+ """Lightweight feature for list operations."""
+ id: str
+ name: str
+ status: str
+
+class DetailedFeature(SimplifiedFeature):
+ """Extended feature with complete details."""
+ description: str | None = None
+ created_at: str
+ updated_at: str
+
+ @classmethod
+ def from_api_response(cls, data: dict) -> "DetailedFeature":
+ """Transform API response to model."""
+ attributes = data.get("attributes", {})
+ return cls(
+ id=data["id"],
+ name=attributes["name"],
+ status=attributes["status"],
+ description=attributes.get("description"),
+ created_at=attributes["created_at"],
+ updated_at=attributes["updated_at"],
+ )
+```
+
+3. **No registration needed** - the tool loader auto-discovers BaseTool subclasses
+
+### Adding Tools to Prowler Hub/Docs
+
+Use the `@mcp.tool()` decorator directly:
+
+```python
+# prowler_hub/server.py
+@hub_mcp_server.tool()
+async def new_hub_tool(param: str) -> dict:
+ """Tool description for LLM."""
+ response = prowler_hub_client.get("/endpoint")
+ return response.json()
+```
+
+---
+
+## Code Quality Standards
+
+### Tool Docstrings
+
+Tool docstrings become AI agent descriptions. Write them in a clear, concise manner focusing on LLM-relevant behavior:
+
+```python
+async def search_security_findings(
+ self,
+ severity: list[str] = Field(default=[], description="Filter by severity levels")
+) -> dict:
+ """Search security findings with advanced filtering.
+
+ Returns a lightweight list of findings optimized for LLM consumption.
+ Use get_finding_details for complete information about a specific finding.
+ """
+```
+
+### Model Design
+
+- Use `MinimalSerializerMixin` to exclude None/empty values
+- Implement `from_api_response()` for consistent API transformation
+- Create two-tier models: Simplified (lists) and Detailed (single items)
+
+### Error Handling
+
+Return structured error responses rather than raising exceptions:
+
+```python
+try:
+ response = await self.api_client.get(f"/api/v1/items/{item_id}")
+ return DetailedItem.from_api_response(response["data"]).model_dump()
+except Exception as e:
+ self.logger.error(f"Failed to get item {item_id}: {e}")
+ return {"error": str(e), "status": "failed"}
+```
+
+---
+
+## QA Checklist Before Commit
+
+- [ ] Tool docstrings are clear and describe LLM-relevant behavior
+- [ ] Models use `MinimalSerializerMixin` for LLM optimization
+- [ ] API responses are transformed to simplified models
+- [ ] No hardcoded secrets or API keys
+- [ ] Error handling returns structured responses
+- [ ] New tools are auto-discovered (BaseTool subclass) or properly decorated
+- [ ] Parameter descriptions use Pydantic `Field()` with clear descriptions
+
+---
+
+## References
+
+- **Root Project Guide**: `../AGENTS.md`
+- **FastMCP Documentation**: https://gofastmcp.com/llms.txt
+- **Prowler API Documentation**: https://api.prowler.com/api/v1/docs
diff --git a/mcp_server/README.md b/mcp_server/README.md
index e4d55fabe8..41edce8cc0 100644
--- a/mcp_server/README.md
+++ b/mcp_server/README.md
@@ -1,18 +1,59 @@
# Prowler MCP Server
-> ⚠️ **Preview Feature**: This MCP server is currently in preview and under active development. Features and functionality may change. We welcome your feedback—please report any issues on [GitHub](https://github.com/prowler-cloud/prowler/issues) or join our [Slack community](https://goto.prowler.com/slack) to discuss and share your thoughts.
+**Prowler MCP Server** brings the entire Prowler ecosystem to AI assistants through the [Model Context Protocol (MCP)](https://modelcontextprotocol.io). It enables seamless integration with AI tools like Claude Desktop, Cursor, and other MCP clients, allowing interaction with Prowler's security capabilities through natural language.
-Access the entire Prowler ecosystem through the Model Context Protocol (MCP). This server provides three main capabilities:
+> **Preview Feature**: This MCP server is currently under active development. Features and functionality may change. We welcome your feedback—please report any issues on [GitHub](https://github.com/prowler-cloud/prowler/issues) or join our [Slack community](https://goto.prowler.com/slack).
-- **Prowler Cloud and Prowler App (Self-Managed)**: Full access to Prowler Cloud platform and Prowler Self-Managed for managing providers, running scans, and analyzing security findings
-- **Prowler Hub**: Access to Prowler's security checks, fixers, and compliance frameworks catalog
-- **Prowler Documentation**: Search and retrieve official Prowler documentation
+## Key Capabilities
-## Quick Start with Hosted Server (Recommended)
+### Prowler Cloud and Prowler App (Self-Managed)
-**The easiest way to use Prowler MCP is through our hosted server at `https://mcp.prowler.com/mcp`**
+Full access to Prowler Cloud platform and self-managed Prowler App for:
+- **Findings Analysis**: Query, filter, and analyze security findings across all your cloud environments
+- **Provider Management**: Create, configure, and manage your configured Prowler providers (AWS, Azure, GCP, etc.)
+- **Scan Orchestration**: Trigger on-demand scans and schedule recurring security assessments
+- **Resource Inventory**: Search and view detailed information about your audited resources
+- **Muting Management**: Create and manage muting rules to suppress non-critical findings
-No installation required! Just configure your MCP client:
+### Prowler Hub
+
+Access to Prowler's comprehensive security knowledge base:
+- **Security Checks Catalog**: Browse and search **over 1000 security checks** across multiple Prowler providers
+- **Check Implementation**: View the Python code that powers each security check
+- **Automated Fixers**: Access remediation scripts for common security issues
+- **Compliance Frameworks**: Explore mappings to **over 70 compliance standards and frameworks**
+- **Provider Services**: View available services and checks for each cloud provider
+
+### Prowler Documentation
+
+Search and retrieve official Prowler documentation:
+- **Intelligent Search**: Full-text search across all Prowler documentation
+- **Contextual Results**: Get relevant documentation pages with highlighted snippets
+- **Document Retrieval**: Access complete markdown content of any documentation file
+
+## Documentation
+
+For comprehensive guides and tutorials, see the official documentation:
+
+| Guide | Description |
+|-------|-------------|
+| [Overview](https://docs.prowler.com/getting-started/products/prowler-mcp) | Key capabilities, use cases, and deployment options |
+| [Installation](https://docs.prowler.com/getting-started/installation/prowler-mcp) | Docker, PyPI, and source installation |
+| [Configuration](https://docs.prowler.com/getting-started/basic-usage/prowler-mcp) | Configure Claude Desktop, Cursor, and other MCP clients |
+| [Tools Reference](https://docs.prowler.com/getting-started/basic-usage/prowler-mcp-tools) | Complete reference of all tools |
+| [Developer Guide](https://docs.prowler.com/developer-guide/mcp-server) | How to extend with new tools |
+
+## Deployment Options
+
+Prowler MCP Server can be used in three ways:
+
+### 1. Prowler Cloud MCP Server (Recommended)
+
+**Use Prowler's managed MCP server at `https://mcp.prowler.com/mcp`**
+
+- No installation required
+- Managed and maintained by Prowler team
+- Always up-to-date
```json
{
@@ -30,70 +71,37 @@ No installation required! Just configure your MCP client:
}
```
-**Configuration file locations:**
-- **Claude Desktop (macOS)**: `~/Library/Application Support/Claude/claude_desktop_config.json`
-- **Claude Desktop (Windows)**: `%AppData%\Claude\claude_desktop_config.json`
-- **Cursor**: `~/.cursor/mcp.json`
+### 2. Local STDIO Mode
-Get your API key at [Prowler Cloud](https://cloud.prowler.com) → Settings → API Keys
+**Run the server locally on your machine**
-> **Benefits:** Always up-to-date, no maintenance, managed by Prowler team
+- Runs as a subprocess of your MCP client
+- Requires Python 3.12+ or Docker
-## Local/Self-Hosted Installation
+### 3. Self-Hosted HTTP Mode
-If you need to run the MCP server locally or self-host it, choose one of the following installation methods. **Configuration is the same** for both managed and local installations - just point to your local server URL instead of `https://mcp.prowler.com/mcp`.
+**Deploy your own remote MCP server**
-### Requirements
+- Full control over deployment
+- Requires Python 3.12+ or Docker
-- Python 3.12+ (for source/PyPI installation)
-- Docker (for Docker installation)
-- Network access to `https://hub.prowler.com` (for Prowler Hub)
-- Network access to `https://prowler.mintlify.app` (for Prowler Documentation)
-- Network access to Prowler Cloud and Prowler App (Self-Managed) API (optional, only for Prowler Cloud/App features)
-- Prowler Cloud account credentials (only for Prowler Cloud and Prowler App features)
+See the [Installation Guide](https://docs.prowler.com/getting-started/installation/prowler-mcp) for complete instructions.
-### Installation Methods
+## Quick Installation
-#### Option 1: Docker Hub (Recommended)
-
-Pull the official image from Docker Hub:
+### Docker (Recommended)
```bash
docker pull prowlercloud/prowler-mcp
-```
-Run in STDIO mode:
-```bash
+# STDIO mode
docker run --rm -i prowlercloud/prowler-mcp
+
+# HTTP mode
+docker run --rm -p 8000:8000 prowlercloud/prowler-mcp --transport http --host 0.0.0.0 --port 8000
```
-Run in HTTP mode:
-```bash
-docker run --rm -p 8000:8000 \
- prowlercloud/prowler-mcp \
- --transport http --host 0.0.0.0 --port 8000
-```
-
-With environment variables:
-```bash
-docker run --rm -i \
- -e PROWLER_APP_API_KEY="pk_your_api_key" \
- -e API_BASE_URL="https://api.prowler.com/api/v1" \
- prowlercloud/prowler-mcp
-```
-
-**Docker Hub:** [prowlercloud/prowler-mcp](https://hub.docker.com/r/prowlercloud/prowler-mcp)
-
-#### Option 2: PyPI Package (Coming Soon)
-
-```bash
-pip install prowler-mcp-server
-prowler-mcp --help
-```
-
-#### Option 3: From Source (Development)
-
-Clone the repository and use `uv`:
+### From Source
```bash
git clone https://github.com/prowler-cloud/prowler.git
@@ -101,400 +109,86 @@ cd prowler/mcp_server
uv run prowler-mcp --help
```
-Install [uv](https://docs.astral.sh/uv/) first if needed.
-
-#### Option 4: Build Docker Image from Source
-
-```bash
-git clone https://github.com/prowler-cloud/prowler.git
-cd prowler/mcp_server
-docker build -t prowler-mcp .
-docker run --rm -i prowler-mcp
-```
-
-## Running
-
-The Prowler MCP server supports two transport modes:
-- **STDIO mode** (default): For direct integration with MCP clients like Claude Desktop
-- **HTTP mode**: For remote access over HTTP with Bearer token authentication
-
-### Transport Modes
-
-#### STDIO Mode (Default)
-
-STDIO mode is the standard MCP transport for direct client integration:
-
-```bash
-cd prowler/mcp_server
-uv run prowler-mcp
-# or
-uv run prowler-mcp --transport stdio
-```
-
-#### HTTP Mode (Remote Server)
-
-HTTP mode allows the server to run as a remote service accessible over HTTP:
-
-```bash
-cd prowler/mcp_server
-# Run on default host and port (127.0.0.1:8000)
-uv run prowler-mcp --transport http
-
-# Run on custom host and port
-uv run prowler-mcp --transport http --host 0.0.0.0 --port 8080
-```
-
-For self-deployed MCP remote server, you can use also configure the server to use a custom API base URL with the environment variable `API_BASE_URL`; and the transport mode with the environment variable `PROWLER_MCP_TRANSPORT_MODE`.
-
-```bash
-export API_BASE_URL="https://api.prowler.com/api/v1"
-export PROWLER_MCP_TRANSPORT_MODE="http"
-```
-
-### Using uv directly
-
-After installation, start the MCP server via the console script:
-
-```bash
-cd prowler/mcp_server
-uv run prowler-mcp
-```
-
-Alternatively, you can run from wherever you want using `uvx` command:
-
-```bash
-uvx /path/to/prowler/mcp_server/
-```
-
-### Using Docker
-
-#### STDIO Mode (Default)
-
-Run the pre-built Docker container in STDIO mode:
-
-```bash
-cd prowler/mcp_server
-docker run --rm --env-file ./.env -it prowler-mcp
-```
-
-#### HTTP Mode (Remote Server)
-
-Run as a remote HTTP server:
-
-```bash
-cd prowler/mcp_server
-# Run on port 8000 (accessible from host)
-docker run --rm --env-file ./.env -p 8000:8000 -it prowler-mcp --transport http --host 0.0.0.0 --port 8000
-
-# Run on custom port
-docker run --rm --env-file ./.env -p 8080:8080 -it prowler-mcp --transport http --host 0.0.0.0 --port 8080
-```
-
-## Production Deployment
-
-For production deployments that require customization, it is recommended to use the ASGI application that can be found in `prowler_mcp_server.server`. This can be run with uvicorn:
-
-```bash
-uvicorn prowler_mcp_server.server:app --host 0.0.0.0 --port 8000
-```
-
-For more details on production deployment options, see the [FastMCP production deployment guide](https://gofastmcp.com/deployment/http#production-deployment) and [uvicorn settings](https://www.uvicorn.org/settings/).
-
-## Command Line Arguments
-
-The Prowler MCP server supports the following command line arguments:
-
-```
-prowler-mcp [--transport {stdio,http}] [--host HOST] [--port PORT]
-```
-
-**Arguments:**
-- `--transport {stdio,http}`: Transport method (default: stdio)
- - `stdio`: Standard input/output transport for direct MCP client integration
- - `http`: HTTP transport for remote server access
-- `--host HOST`: Host to bind to for HTTP transport (default: 127.0.0.1)
-- `--port PORT`: Port to bind to for HTTP transport (default: 8000)
-
-**Examples:**
-```bash
-# Default STDIO mode
-prowler-mcp
-
-# Explicit STDIO mode
-prowler-mcp --transport stdio
-
-# HTTP mode with default host and port (127.0.0.1:8000)
-prowler-mcp --transport http
-
-# HTTP mode accessible from any network interface
-prowler-mcp --transport http --host 0.0.0.0
-
-# HTTP mode with custom port
-prowler-mcp --transport http --host 0.0.0.0 --port 8080
-```
-
## Available Tools
-### Prowler Hub
+For complete tool descriptions and parameters, see the [Tools Reference](https://docs.prowler.com/getting-started/basic-usage/prowler-mcp-tools).
-All tools are exposed under the `prowler_hub` prefix.
+### Tool Naming Convention
-- `prowler_hub_get_check_filters`: Return available filter values for checks (providers, services, severities, categories, compliances). Call this before `prowler_hub_get_checks` to build valid queries.
-- `prowler_hub_get_checks`: List checks with option of advanced filtering.
-- `prowler_hub_get_check_raw_metadata`: Fetch raw check metadata JSON (low-level version of get_checks).
-- `prowler_hub_get_check_code`: Fetch check implementation Python code from Prowler.
-- `prowler_hub_get_check_fixer`: Fetch check fixer Python code from Prowler (if it exists).
-- `prowler_hub_search_checks`: Full‑text search across check metadata.
-- `prowler_hub_get_compliance_frameworks`: List/filter compliance frameworks.
-- `prowler_hub_search_compliance_frameworks`: Full-text search across frameworks.
-- `prowler_hub_list_providers`: List Prowler official providers and their services.
-- `prowler_hub_get_artifacts_count`: Return total artifact count (checks + frameworks).
+All tools follow a consistent naming pattern with prefixes:
+- `prowler_app_*` - Prowler Cloud and App (Self-Managed) management tools
+- `prowler_hub_*` - Prowler Hub catalog and compliance tools
+- `prowler_docs_*` - Prowler documentation search and retrieval
-### Prowler Documentation
+## Architecture
-All tools are exposed under the `prowler_docs` prefix.
-
-- `prowler_docs_search`: Search the official Prowler documentation using fulltext search. Returns relevant documentation pages with highlighted snippets and relevance scores.
-- `prowler_docs_get_document`: Retrieve the full markdown content of a specific documentation file using the path from search results.
-
-### Prowler Cloud and Prowler App (Self-Managed)
-
-All tools are exposed under the `prowler_app` prefix.
-
-#### Findings Management
-- `prowler_app_list_findings`: List security findings from Prowler scans with advanced filtering
-- `prowler_app_get_finding`: Get detailed information about a specific security finding
-- `prowler_app_get_latest_findings`: Retrieve latest findings from the latest scans for each provider
-- `prowler_app_get_findings_metadata`: Fetch unique metadata values from filtered findings
-- `prowler_app_get_latest_findings_metadata`: Fetch metadata from latest findings across all providers
-
-#### Provider Management
-- `prowler_app_list_providers`: List all providers with filtering options
-- `prowler_app_create_provider`: Create a new provider in the current tenant
-- `prowler_app_get_provider`: Get detailed information about a specific provider
-- `prowler_app_update_provider`: Update provider details (alias, etc.)
-- `prowler_app_delete_provider`: Delete a specific provider
-- `prowler_app_test_provider_connection`: Test provider connection status
-
-#### Provider Secrets Management
-- `prowler_app_list_provider_secrets`: List all provider secrets with filtering
-- `prowler_app_add_provider_secret`: Add or update credentials for a provider
-- `prowler_app_get_provider_secret`: Get detailed information about a provider secret
-- `prowler_app_update_provider_secret`: Update provider secret details
-- `prowler_app_delete_provider_secret`: Delete a provider secret
-
-#### Scan Management
-- `prowler_app_list_scans`: List all scans with filtering options
-- `prowler_app_create_scan`: Trigger a manual scan for a specific provider
-- `prowler_app_get_scan`: Get detailed information about a specific scan
-- `prowler_app_update_scan`: Update scan details
-- `prowler_app_get_scan_compliance_report`: Download compliance report as CSV
-- `prowler_app_get_scan_report`: Download ZIP file containing scan report
-
-#### Schedule Management
-- `prowler_app_schedules_daily_scan`: Create a daily scheduled scan for a provider
-
-#### Processor Management
-- `prowler_app_processors_list`: List all processors with filtering
-- `prowler_app_processors_create`: Create a new processor. For now, only mute lists are supported.
-- `prowler_app_processors_retrieve`: Get processor details by ID
-- `prowler_app_processors_partial_update`: Update processor configuration
-- `prowler_app_processors_destroy`: Delete a processor
-
-## Configuration
-
-### Prowler Cloud and Prowler App (Self-Managed) Authentication
-
-> [!IMPORTANT]
-> Authentication is not needed for using Prowler Hub or Prowler Documentation features.
-
-The Prowler MCP server supports different authentication in Prowler Cloud and Prowler App (Self-Managed) methods depending on the transport mode:
-
-#### STDIO Mode Authentication
-
-For STDIO mode, authentication is handled via environment variables using an API key:
-
-```bash
-# Required for Prowler Cloud and Prowler App (Self-Managed) authentication
-export PROWLER_APP_API_KEY="pk_your_api_key_here"
-
-# Optional - for custom API endpoint, in case not provided Prowler Cloud API will be used
-export API_BASE_URL="https://api.prowler.com/api/v1"
+```
+prowler_mcp_server/
+├── server.py # Main orchestrator (imports sub-servers with prefixes)
+├── main.py # CLI entry point
+├── prowler_hub/ # tools - no authentication required
+├── prowler_app/ # tools - authentication required
+│ ├── tools/ # Tool implementations
+│ ├── models/ # Pydantic models for LLM-optimized responses
+│ └── utils/ # API client, authentication, tool loader
+└── prowler_documentation/ # tools - no authentication required
```
-#### HTTP Mode Authentication
+**Key Features:**
+- **Modular Design**: Three independent sub-servers with prefixed namespacing
+- **Auto-Discovery**: Prowler App tools are automatically discovered and registered
+- **LLM Optimization**: Response models minimize token usage by excluding empty values
+- **Dual Transport**: Supports both STDIO (local) and HTTP (remote) modes
-For HTTP mode (remote server), authentication is handled via Bearer tokens. The MCP server supports both JWT tokens and API keys:
+## Use Cases
-**Option 1: Using API Keys (Recommended)**
-Use your Prowler API key directly in the MCP client configuration with Bearer token format:
-```
-Authorization: Bearer pk_your_api_key_here
-```
+The Prowler MCP Server enables powerful workflows through AI assistants:
-**Option 2: Using JWT Tokens**
-You need to obtain a JWT token from Prowler Cloud/App and include the generated token in the MCP client configuration. To get a valid token, you can use the following command (replace the email and password with your own credentials):
+**Security Operations**
+- "Show me all critical findings from my AWS production accounts"
+- "Register my new AWS account in Prowler and run a scheduled scan every day"
+- "List all muted findings and detect what findgings are muted by a not enough good reason in relation to their severity"
-```bash
-curl -X POST https://api.prowler.com/api/v1/tokens \
- -H "Content-Type: application/vnd.api+json" \
- -H "Accept: application/vnd.api+json" \
- -d '{
- "data": {
- "type": "tokens",
- "attributes": {
- "email": "your-email@example.com",
- "password": "your-password"
- }
- }
- }'
-```
+**Security Research**
+- "Explain what the S3 bucket public access Prowler check does"
+- "Find all Prowler checks related to encryption at rest"
+- "What is the latest version of the CIS that Prowler is covering per provider?"
-The response will be a JWT token that you can use to [authenticate your MCP client](#http-mode-configuration-remote-server).
+**Documentation & Learning**
+- "How do I configure Prowler to scan my GCP organization?"
+- "What authentication methods does Prowler support for Azure?"
+- "How can I contribute with a new security check to Prowler?"
-### MCP Client Configuration
+## Requirements
-Configure your MCP client, like Claude Desktop, Cursor, etc, to connect to the server. The configuration depends on whether you're running in STDIO mode (local) or HTTP mode (remote).
+**For Prowler Cloud MCP Server:**
+- Prowler Cloud account and API key (only for Prowler Cloud/App features)
-#### STDIO Mode Configuration
+**For self-hosted STDIO/HTTP Mode:**
+- Python 3.12+ or Docker
+- Network access to:
+ - `https://hub.prowler.com` (for Prowler Hub)
+ - `https://docs.prowler.com` (for Prowler Documentation)
+ - Prowler Cloud API or self-hosted Prowler App API (for Prowler Cloud/App features)
-For local execution, configure your MCP client to launch the server directly. Below are examples for both direct execution and Docker deployment; consult your client's documentation for exact locations.
+> **No Authentication Required**: Prowler Hub and Prowler Documentation features work without authentication. A Prowler API key is only required to access Prowler Cloud or Prowler App (Self-Managed) features.
-##### Using uvx (Direct Execution)
+## Configuring MCP Hosts
-```json
-{
- "mcpServers": {
- "prowler": {
- "command": "uvx",
- "args": ["/path/to/prowler/mcp_server/"],
- "env": {
- "PROWLER_APP_API_KEY": "pk_your_api_key_here",
- "API_BASE_URL": "https://api.prowler.com/api/v1" // Optional, in case not provided Prowler Cloud API will be used
- }
- }
- }
-}
-```
+To configure your MCP host (Claude Code, Cursor, etc.) see the [Configuration Guide](https://docs.prowler.com/getting-started/basic-usage/prowler-mcp) for detailed setup instructions.
-##### Using Docker
+## Contributing
-```json
-{
- "mcpServers": {
- "prowler": {
- "command": "docker",
- "args": [
- "run", "--rm", "-i",
- "--env", "PROWLER_APP_API_KEY=pk_your_api_key_here",
- "--env", "API_BASE_URL=https://api.prowler.com/api/v1", // Optional, in case not provided Prowler Cloud API will be used
- "prowler-mcp"
- ]
- }
- }
-}
-```
+For developers looking to extend the MCP server with new tools or features:
-#### HTTP Mode Configuration (Remote Server)
+- **[Developer Guide](https://docs.prowler.com/developer-guide/mcp-server)**: Step-by-step instructions for adding new tools
+- **[AGENTS.md](./AGENTS.md)**: AI agent guidelines and coding patterns
-For HTTP mode, you can configure your MCP client to connect to a remote Prowler MCP server.
+## Related Products
-Most MCP clients don't natively support HTTP transport with Bearer token authentication. However, you can use the `mcp-remote` proxy tool to connect any MCP client to remote HTTP servers.
-
-##### Using mcp-remote Proxy (Recommended for Claude Desktop)
-
-For clients like Claude Desktop that don't support HTTP transport natively, use the `mcp-remote` npm package as a proxy:
-
-**Using API Key (Recommended):**
-```json
-{
- "mcpServers": {
- "prowler": {
- "command": "npx",
- "args": [
- "mcp-remote",
- "https://mcp.prowler.com/mcp",
- "--header",
- "Authorization: Bearer pk_your_api_key_here"
- ]
- }
- }
-}
-```
-
-**Using JWT Token:**
-```json
-{
- "mcpServers": {
- "prowler": {
- "command": "npx",
- "args": [
- "mcp-remote",
- "https://mcp.prowler.com/mcp",
- "--header",
- "Authorization: Bearer "
- ]
- }
- }
-}
-```
-
-> **Note:** Replace `https://mcp.prowler.com/mcp` with your actual MCP server URL (use `http://localhost:8000/mcp` for local deployment). The `mcp-remote` package is automatically installed by `npx` on first use.
-
-> **Info:** The `mcp-remote` tool acts as a bridge, converting STDIO protocol (used by Claude Desktop) to HTTP requests (used by the remote MCP server). Learn more at [mcp-remote on npm](https://www.npmjs.com/package/mcp-remote).
-
-##### Direct HTTP Configuration (For Compatible Clients)
-
-For clients that natively support HTTP transport with Bearer token authentication:
-
-**Using API Key:**
-```json
-{
- "mcpServers": {
- "prowler": {
- "url": "https://mcp.prowler.com/mcp",
- "headers": {
- "Authorization": "Bearer pk_your_api_key_here"
- }
- }
- }
-}
-```
-
-**Using JWT Token:**
-```json
-{
- "mcpServers": {
- "prowler": {
- "url": "https://mcp.prowler.com/mcp",
- "headers": {
- "Authorization": "Bearer "
- }
- }
- }
-}
-```
-
-> **Note:** Replace `mcp.prowler.com` with your actual server hostname and adjust the port if needed (e.g., `http://localhost:8000/mcp` for local deployment).
-
-### Claude Desktop (macOS/Windows)
-
-Add the example server to Claude Desktop's config file, then restart the app.
-
-- macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`
-- Windows: `%AppData%\Claude\claude_desktop_config.json` (e.g. `C:\\Users\\\\AppData\\Roaming\\Claude\\claude_desktop_config.json`)
-
-### Cursor (macOS/Linux)
-
-If you want to have it globally available, add the example server to Cursor's config file, then restart the app.
-
-- macOS/Linux: `~/.cursor/mcp.json`
-
-If you want to have it only for the current project, add the example server to the project's root in a new `.cursor/mcp.json` file.
-
-## Documentation
-
-For detailed documentation about the Prowler MCP Server, including guides, tutorials, and use cases, visit the [official Prowler documentation](https://docs.prowler.com).
+- **[Prowler Hub](https://hub.prowler.com)**: Browse security checks and compliance frameworks
+- **[Prowler Cloud](https://cloud.prowler.com)**: Managed Prowler platform
+- **[Lighthouse AI](https://docs.prowler.com/getting-started/products/prowler-lighthouse-ai)**: AI security analyst
## License