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 Prowler MCP Server Schema Prowler MCP Server Schema -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