### PresetsResult Example Source: https://github.com/garootman/drheaderplus-mcp/blob/main/_autodocs/types.md An example of the PresetsResult type, which maps preset names to their file paths. Exact paths may vary based on installation. ```python { "owasp-asvs-v14": "/usr/local/lib/python3.12/site-packages/drheaderplus/rules/owasp_asvs_v14.yaml", "default": "/usr/local/lib/python3.12/site-packages/drheaderplus/rules/default.yaml" } ``` -------------------------------- ### Client Capabilities Example Source: https://github.com/garootman/drheaderplus-mcp/blob/main/_autodocs/mcp-protocol.md An example of the JSON structure representing a client's capabilities during negotiation. ```json { "clientInfo": { "name": "claude-desktop", "version": "1.0" }, "capabilities": { "roots": { "listChanged": true } } } ``` -------------------------------- ### Example Finding Object Source: https://github.com/garootman/drheaderplus-mcp/blob/main/_autodocs/types.md Illustrates a concrete example of a 'Finding' object, showing the expected data for a security header audit result. ```python finding = { "rule": "Strict-Transport-Security", "severity": "high", "message": "max-age should be at least 31536000 (1 year), found 3600", "value": "max-age=3600" } ``` -------------------------------- ### Install drheaderplus-mcp using uvx Source: https://github.com/garootman/drheaderplus-mcp/blob/main/README.md Use this command to quickly install and run the drheaderplus-mcp server. ```bash uvx drheaderplus-mcp ``` -------------------------------- ### Complete Pre-Deployment Header Validation Example Source: https://github.com/garootman/drheaderplus-mcp/blob/main/_autodocs/tool-usage-guide.md A comprehensive example function to validate production header configurations against OWASP ASVS compliance before deployment. It raises an error for critical issues and warns about non-critical ones. ```python async def validate_headers_before_deploy(): """Validate production header configuration.""" production_headers = { "Strict-Transport-Security": "max-age=31536000; includeSubDomains", "Content-Security-Policy": "default-src 'self'", "X-Content-Type-Options": "nosniff", "X-Frame-Options": "DENY", "Referrer-Policy": "strict-origin-when-cross-origin" } # Check against OWASP compliance findings = await mcp.call_tool("analyze_headers", { "headers": production_headers, "preset": "owasp-asvs-v14" }) if findings: high_severity = [f for f in findings if f["severity"] == "high"] if high_severity: raise RuntimeError( f"Cannot deploy: {len(high_severity)} critical issues:\n" + "\n".join(f" - {f['rule']}: {f['message']}" for f in high_severity) ) else: print(f"Warning: {len(findings)} non-critical issues found") for f in findings: print(f" [{f['severity']}] {f['rule']}: {f['message']}") else: print("✓ Headers approved for deployment") return len([f for f in findings if f["severity"] == "high"]) == 0 ``` -------------------------------- ### Server Capabilities Example (drheaderplus-mcp) Source: https://github.com/garootman/drheaderplus-mcp/blob/main/_autodocs/mcp-protocol.md An example of the JSON structure representing the server's (drheaderplus-mcp) capabilities. ```json { "serverInfo": { "name": "drheaderplus", "version": "0.1.0" }, "capabilities": { "tools": {} } } ``` -------------------------------- ### Example Subprocess Handling Source: https://github.com/garootman/drheaderplus-mcp/blob/main/_autodocs/MANIFEST.md Demonstrates how to handle subprocess failures by checking non-zero exit codes. ```python import subprocess def run_command(command): result = subprocess.run(command, capture_output=True, text=True) if result.returncode != 0: print(f"Error: Command failed with exit code {result.returncode}") print(f"Stderr: {result.stderr}") # Handle error appropriately else: print(f"Stdout: {result.stdout}") # Process successful output # Example usage: # run_command(['your_command', 'arg1']) ``` -------------------------------- ### Example HTTP Headers for Analysis Source: https://github.com/garootman/drheaderplus-mcp/blob/main/_autodocs/configuration.md Provides an example of how HTTP response headers should be formatted as a dictionary for the analyze_headers function. This includes common security-related headers. ```python { "Strict-Transport-Security": "max-age=31536000; includeSubDomains", "Content-Security-Policy": "default-src 'self'", "X-Content-Type-Options": "nosniff" } ``` -------------------------------- ### Install development dependencies and run tests Source: https://github.com/garootman/drheaderplus-mcp/blob/main/README.md Install drheaderplus-mcp in editable mode with development dependencies and run pytest. ```bash pip install -e ".[dev]" python -m pytest tests/ -v ``` -------------------------------- ### Install DrHeaderPlus MCP in Development Mode Source: https://github.com/garootman/drheaderplus-mcp/blob/main/CLAUDE.md Installs the package in editable mode for development. Use this to make local changes reflected immediately. ```bash pip install -e . ``` -------------------------------- ### Install drheaderplus-mcp using pip Source: https://github.com/garootman/drheaderplus-mcp/blob/main/README.md Install the drheaderplus-mcp package using pip for system-wide access. ```bash pip install drheaderplus-mcp ``` -------------------------------- ### Install DrHeaderPlus MCP with Development Dependencies Source: https://github.com/garootman/drheaderplus-mcp/blob/main/CLAUDE.md Installs the package in editable mode along with development tools like pytest and pytest-asyncio. Redirects errors to /dev/null. ```bash pip install -e "[dev]" 2>/dev/null || pip install pytest pytest-asyncio responses anyio ``` -------------------------------- ### Install Development Dependencies Source: https://github.com/garootman/drheaderplus-mcp/blob/main/_autodocs/configuration.md Install drheaderplus-mcp in development mode, including all necessary tools for testing and development. This command is used when contributing to the project. ```bash pip install -e ".[dev]" ``` -------------------------------- ### list_presets() Source: https://github.com/garootman/drheaderplus-mcp/blob/main/_autodocs/MANIFEST.md Discovers and lists the available security rulesets (presets). Includes signature, parameter table, return structure, and usage examples. ```APIDOC ## list_presets() ### Description Discovers and lists the available security rulesets (presets). ### Signature `list_presets() -> Dict[str, Any]` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters Table None ### Response #### Success Response (200) - **presets** (Dict[str, Dict[str, Any]]) - A mapping of preset names to their details. ### Response Structure Details - **preset_name** (str) - The name of the preset. - **description** (str) - A description of the preset. - **rules** (List[str]) - A list of rules included in the preset. ### Request Example ```python # Example usage (not actual code, conceptual) presets = drheaderplus_mcp.list_presets() print(presets) ``` ### Response Example ```json { "presets": { "default": { "description": "Default security checks.", "rules": ["header-not-present", "insecure-transport"] }, "owasp-asvs-v14": { "description": "OWASP ASVS v1.4 compliance checks.", "rules": ["csp-header-missing", "x-frame-options-missing"] } } } ``` ``` -------------------------------- ### Comparison of Staging vs Production Headers Findings Source: https://github.com/garootman/drheaderplus-mcp/blob/main/docs/examples.md Example JSON output comparing header findings between staging and production environments. This helps spot differences in security configurations. ```json [ {"url": "https://staging.myapp.com", "issues": 0, "findings": []}, {"url": "https://myapp.com", "issues": 2, "findings": [ {"rule": "Content-Security-Policy", "severity": "high", "message": "Header not included in response", "value": ""}, {"rule": "Permissions-Policy", "severity": "medium", "message": "Header not included in response", "value": ""} ]} ] ``` -------------------------------- ### Example MCP Stream with JSON-RPC 2.0 Source: https://github.com/garootman/drheaderplus-mcp/blob/main/_autodocs/mcp-protocol.md Illustrates a typical stream of JSON-RPC 2.0 messages over stdio, including initialization and tool listing requests and responses. ```text {"jsonrpc":"2.0","id":1,"method":"initialize",...}\n {"jsonrpc":"2.0","id":1,"result":{...}}\n {"jsonrpc":"2.0","id":2,"method":"tools/list"}\n {"jsonrpc":"2.0","id":2,"result":{...}}\n ``` -------------------------------- ### List Available Ruleset Presets Source: https://github.com/garootman/drheaderplus-mcp/blob/main/_autodocs/api-reference.md Call this function to get a dictionary of available ruleset preset names and their corresponding file paths. The availability of presets depends on the installed version of the drheaderplus package. ```python def list_presets() -> dict[str, str]: """Queries the PRESETS mapping from the underlying drheaderplus package. Returns a snapshot of available presets at server startup. Preset availability depends on the installed version of drheaderplus. """ # Implementation details omitted for brevity pass ``` ```python # Discover available presets presets = list_presets() print("Available presets:") for name, path in presets.items(): print(f" {name}: {path}") # Use a discovered preset if "owasp-asvs-v14" in presets: findings = scan_url( "https://example.com", preset="owasp-asvs-v14" ) ``` -------------------------------- ### Manual MCP Protocol Testing with Netcat Source: https://github.com/garootman/drheaderplus-mcp/blob/main/_autodocs/mcp-protocol.md Demonstrates manual testing of the MCP protocol by starting the server and sending a JSON-RPC request using netcat. This is illustrative for socket transport; stdio transport does not use a network socket. ```bash # Start the server in one terminal python -m drheaderplus_mcp # In another terminal, send a JSON-RPC request echo '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' | nc localhost 9999 ``` -------------------------------- ### Example Findings for Single URL Scan Source: https://github.com/garootman/drheaderplus-mcp/blob/main/docs/examples.md Example JSON output showing security header issues found during a scan. An empty list indicates all checks passed. ```json [ {"rule": "Strict-Transport-Security", "severity": "high", "message": "Header not included in response", "value": ""}, {"rule": "Content-Security-Policy", "severity": "high", "message": "Header not included in response", "value": ""}, {"rule": "X-Content-Type-Options", "severity": "medium", "message": "Header not included in response", "value": ""} ] ``` -------------------------------- ### Set Content-Security-Policy Header in Apache Source: https://github.com/garootman/drheaderplus-mcp/blob/main/docs/security-headers-guide.md Configure Apache to implement a Content-Security-Policy. This example sets a baseline policy for self-sourced content and data URIs for images. ```apache Header always set Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self'; img-src 'self' data:; font-src 'self'" ``` -------------------------------- ### BulkScanResult Success Example Source: https://github.com/garootman/drheaderplus-mcp/blob/main/_autodocs/types.md Illustrates a successful result from a bulk scan operation, including the scanned URL, issue count, and a list of findings. ```python { "url": "https://secure.example.com", "issues": 2, "findings": [ { "rule": "Permissions-Policy", "severity": "medium", "message": "Header not included in response", "value": "" }, { "rule": "Content-Security-Policy", "severity": "high", "message": "Directive 'frame-ancestors' should be present", "value": "default-src 'self'" } ] } ``` -------------------------------- ### Set Content-Security-Policy Header in Nginx Source: https://github.com/garootman/drheaderplus-mcp/blob/main/docs/security-headers-guide.md Configure Nginx to implement a Content-Security-Policy. This example sets a baseline policy for self-sourced content and data URIs for images. ```nginx add_header Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self'; img-src 'self' data:; font-src 'self'" always; ``` -------------------------------- ### Complete API Endpoint Audit Example Source: https://github.com/garootman/drheaderplus-mcp/blob/main/_autodocs/tool-usage-guide.md An example function to audit an API endpoint with specific presets and cross-origin isolation settings, then categorizing findings by severity. It prints critical issues and a success message if no findings are present. ```python async def audit_api_endpoint(): findings = await mcp.call_tool("scan_url", { "url": "https://api.example.com/v1", "preset": "owasp-asvs-v14", "cross_origin_isolated": False }) # Categorize findings by severity high_severity = [f for f in findings if f["severity"] == "high"] medium_severity = [f for f in findings if f["severity"] == "medium"] low_severity = [f for f in findings if f["severity"] == "low"] if high_severity: print(f"Critical issues ({len(high_severity)}):") for f in high_severity: print(f" - {f['rule']}: {f['message']}") print(f" Current value: {f['value']}") if not findings: print("✓ All security header checks passed!") return {"total": len(findings), "high": len(high_severity)} ``` -------------------------------- ### AnalyzeHeadersResult Example Source: https://github.com/garootman/drheaderplus-mcp/blob/main/_autodocs/types.md Similar to ScanUrlResult, this shows findings from analyzing headers. An empty list signifies that all security checks were successful. ```python [ { "rule": "Referrer-Policy", "severity": "medium", "message": "Value should be one of: no-referrer, strict-origin, strict-origin-when-cross-origin", "value": "unsafe-url" } ] ``` -------------------------------- ### BulkScanResult Failure Example Source: https://github.com/garootman/drheaderplus-mcp/blob/main/_autodocs/types.md Demonstrates a failure case in a bulk scan, showing the URL that could not be scanned and the associated error message. ```python { "url": "https://unreachable.example.com", "error": "Connection refused", "findings": [] } ``` -------------------------------- ### Run the DrHeaderPlus MCP Server Source: https://github.com/garootman/drheaderplus-mcp/blob/main/CLAUDE.md Starts the DrHeaderPlus MCP server using the stdio transport. The server will block and wait for input on standard input. ```bash drheaderplus-mcp ``` -------------------------------- ### Example Finding Format Source: https://github.com/garootman/drheaderplus-mcp/blob/main/docs/api-reference.md This JSON structure represents a single finding from the API. An empty list `[]` indicates that all checks passed for a given scan or analysis. ```json { "rule": "Strict-Transport-Security", "severity": "high", "message": "max-age should be at least 31536000", "value": "max-age=100" } ``` -------------------------------- ### ScanUrlResult Example Source: https://github.com/garootman/drheaderplus-mcp/blob/main/_autodocs/types.md Represents the result of a single URL scan, detailing security header findings. An empty list indicates all checks passed. ```python [ { "rule": "Strict-Transport-Security", "severity": "high", "message": "Header not included in response", "value": "" }, { "rule": "Content-Security-Policy", "severity": "high", "message": "Header not included in response", "value": "" }, { "rule": "X-Content-Type-Options", "severity": "medium", "message": "Header not included in response", "value": "" } ] ``` -------------------------------- ### Custom MCP Client: Spawning and Communicating with Server Source: https://github.com/garootman/drheaderplus-mcp/blob/main/_autodocs/configuration.md Example of a custom Python client that spawns the drheaderplus-mcp server process and communicates with it using JSON-RPC over stdio. This demonstrates sending a tool call request and receiving the response. ```python import subprocess import json process = subprocess.Popen( ["python", "-m", "drheaderplus_mcp"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True ) # Send JSON-RPC request request = { "jsonrpc": "2.0", "id": 1, "method": "tools/call", "params": { "name": "scan_url", "arguments": {"url": "https://example.com"} } } process.stdin.write(json.dumps(request) + "\n") response = process.stdout.readline() print(json.loads(response)) ``` -------------------------------- ### Analyze Headers with Specific Content-Type Source: https://github.com/garootman/drheaderplus-mcp/blob/main/docs/troubleshooting.md Provide headers as a dictionary to the analyze_headers tool. An empty or incomplete dictionary might bypass analysis. This example shows how to pass a Content-Type header. ```json { "tool": "analyze_headers", "arguments": { "headers": { "Content-Type": "text/html" } } } ``` -------------------------------- ### Expected Findings for Weak Header Test Source: https://github.com/garootman/drheaderplus-mcp/blob/main/docs/examples.md Example JSON output showing expected findings when testing a weak HSTS header value. This helps identify specific issues to address. ```json [ {"rule": "Strict-Transport-Security", "severity": "medium", "message": "max-age should be at least 31536000", "value": "max-age=3600"}, {"rule": "Content-Security-Policy", "severity": "medium", "message": "Wildcard (*) found in directive", "value": "default-src *"} ] ``` -------------------------------- ### Call Tool: list_presets Response (Success) Source: https://github.com/garootman/drheaderplus-mcp/blob/main/_autodocs/mcp-protocol.md Server successfully processes the 'list_presets' tool call, returning a mapping of preset names to their paths. ```json { "jsonrpc": "2.0", "id": 6, "result": { "content": [ { "type": "text", "text": "{"owasp-asvs-v14": "/path/to/owasp_asvs_v14.yaml"}" } ] } } ``` -------------------------------- ### Instantiate FastMCP Server Source: https://github.com/garootman/drheaderplus-mcp/blob/main/_autodocs/configuration.md Initializes the FastMCP server with a name and a detailed instruction string. The name identifies the server to MCP clients, and the instructions describe its purpose to AI assistants. ```python mcp = FastMCP( name="drheaderplus", instructions=( "Security header auditing tool. Scan URLs or analyze raw headers " "against security best practices (OWASP, CSP, HSTS, cookie flags, CORS)." ), ) ``` -------------------------------- ### List Available Security Presets Source: https://github.com/garootman/drheaderplus-mcp/blob/main/_autodocs/index.md Use the `list_presets` tool to discover the available security rulesets. This helps in choosing the appropriate preset for your analysis. ```python presets = await mcp.call_tool("list_presets", {}) ``` -------------------------------- ### List Tools Response Source: https://github.com/garootman/drheaderplus-mcp/blob/main/_autodocs/mcp-protocol.md Server responds with a list of available tools, including their names, descriptions, and input schemas. ```json { "jsonrpc": "2.0", "id": 2, "result": { "tools": [ { "name": "scan_url", "description": "Scan a URL and audit its HTTP security headers...", "inputSchema": { /* ... */ } }, { "name": "analyze_headers", "description": "Audit a set of HTTP response headers...", "inputSchema": { /* ... */ } }, { "name": "scan_bulk", "description": "Scan multiple URLs...", "inputSchema": { /* ... */ } }, { "name": "list_presets", "description": "List available ruleset presets...", "inputSchema": { /* ... */ } } ] } } ``` -------------------------------- ### Initialize Request Source: https://github.com/garootman/drheaderplus-mcp/blob/main/_autodocs/mcp-protocol.md Client sends an initialize request to the server, specifying protocol version, capabilities, and client information. ```json { "jsonrpc": "2.0", "id": 1, "method": "initialize", "params": { "protocolVersion": "2024-11-05", "capabilities": {}, "clientInfo": { "name": "claude", "version": "1.0" } } } ``` -------------------------------- ### List Tools Request Source: https://github.com/garootman/drheaderplus-mcp/blob/main/_autodocs/mcp-protocol.md Client sends a request to list available tools on the server. ```json { "jsonrpc": "2.0", "id": 2, "method": "tools/list" } ``` -------------------------------- ### Compare Staging vs Production Headers Source: https://github.com/garootman/drheaderplus-mcp/blob/main/docs/examples.md Scan both staging and production environments to identify configuration drift. The `scan_bulk` command returns per-URL results for easy comparison. ```bash Use drheaderplus to scan both https://staging.myapp.com and https://myapp.com and compare the findings ``` -------------------------------- ### Initialize Response Source: https://github.com/garootman/drheaderplus-mcp/blob/main/_autodocs/mcp-protocol.md Server responds to the initialize request with its protocol version, capabilities, and server information. ```json { "jsonrpc": "2.0", "id": 1, "result": { "protocolVersion": "2024-11-05", "capabilities": { "tools": {} }, "serverInfo": { "name": "drheaderplus", "version": "0.1.0" } } } ``` -------------------------------- ### Correct Usage with Valid Presets Source: https://github.com/garootman/drheaderplus-mcp/blob/main/_autodocs/errors.md Before using a preset, list available presets using 'list_presets' and then select a valid preset name from the returned dictionary keys. This avoids 'Unknown preset' ValueErrors. ```python # First, discover available presets presets = await mcp.call_tool("list_presets", {}) # Then use a valid preset name findings = await mcp.call_tool("scan_url", { "url": "https://example.com", "preset": list(presets.keys())[0] }) ``` -------------------------------- ### Scan a Website Source: https://github.com/garootman/drheaderplus-mcp/blob/main/_autodocs/README.md Scans a given URL to identify security header issues. Use this to get an initial overview of a site's security posture. ```python findings = await mcp.call_tool("scan_url", {"url": "https://example.com"}) print(f"Found {len(findings)} issues") ``` -------------------------------- ### Registering Drheaderplus as an MCP Tool Source: https://github.com/garootman/drheaderplus-mcp/blob/main/_autodocs/api-reference.md This snippet shows how to initialize the FastMCP server for the drheaderplus tool, providing its name and a brief instruction set for AI assistants. ```python mcp = FastMCP( name="drheaderplus", instructions="Security header auditing tool. Scan URLs or analyze raw headers against security best practices (OWASP, CSP, HSTS, cookie flags, CORS).", ) ``` -------------------------------- ### List Available Security Header Presets Source: https://github.com/garootman/drheaderplus-mcp/blob/main/_autodocs/tool-usage-guide.md Discover all available security header rulesets (presets) supported by the tool. This is useful before selecting a preset for scanning or auditing. ```python presets = await mcp.call_tool("list_presets", {}) print("Available presets:") for name, path in presets.items(): print(f" {name}: {path}") ``` -------------------------------- ### Call Tool: list_presets Request Source: https://github.com/garootman/drheaderplus-mcp/blob/main/_autodocs/mcp-protocol.md Client requests to call the 'list_presets' tool to retrieve available ruleset presets. ```json { "jsonrpc": "2.0", "id": 6, "method": "tools/call", "params": { "name": "list_presets", "arguments": {} } } ``` -------------------------------- ### Comparing Staging vs. Production Environments Source: https://github.com/garootman/drheaderplus-mcp/blob/main/_autodocs/tool-usage-guide.md This snippet shows how to use scan_bulk to compare configuration drift between staging and production environments by analyzing their respective findings. It identifies rules present in one environment but not the other. ```python async def compare_environments(): """Check for configuration drift between staging and production.""" urls = [ "https://staging.example.com", "https://production.example.com" ] results = await mcp.call_tool("scan_bulk", {"urls": urls}) findings_by_url = {} for result in results: if "error" in result: findings_by_url[result["url"]] = None else: findings_by_url[result["url"]] = result["findings"] staging_findings = findings_by_url.get(urls[0], []) prod_findings = findings_by_url.get(urls[1], []) staging_rules = {f["rule"] for f in staging_findings} prod_rules = {f["rule"] for f in prod_findings} missing_in_prod = staging_rules - prod_rules extra_in_prod = prod_rules - staging_rules if missing_in_prod or extra_in_prod: print("⚠ Configuration drift detected!") if missing_in_prod: print(f" Fixed in staging but not in production: {missing_in_prod}") if extra_in_prod: print(f" Issues in production but not in staging: {extra_in_prod}") else: print("✓ Staging and production headers match") ``` -------------------------------- ### analyze_headers() Source: https://github.com/garootman/drheaderplus-mcp/blob/main/_autodocs/MANIFEST.md Audits raw HTTP headers provided as a string. Details include signature, parameters, return structure, behavior, error conditions, and usage examples. ```APIDOC ## analyze_headers() ### Description Audits raw HTTP headers provided as a string. ### Signature `analyze_headers(headers: str, preset: Optional[str] = None) -> Dict[str, Any]` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters Table - **headers** (str) - Required - The raw HTTP headers as a string. - **preset** (Optional[str]) - Optional - The ruleset to use for auditing. ### Response #### Success Response (200) - **findings** (List[Dict[str, Any]]) - A list of findings from the audit. #### Error Response - **error** (str) - Description of the error. ### Request Example ```python # Example usage (not actual code, conceptual) raw_headers = "HTTP/1.1 200 OK\r\nContent-Type: application/json\r\nServer: nginx\r\n\r\n" result = drheaderplus_mcp.analyze_headers(raw_headers, preset="default") print(result) ``` ### Response Example ```json { "findings": [ { "rule": "header-not-present", "severity": "medium", "message": "X-Frame-Options header is not present.", "value": null } ] } ``` ``` -------------------------------- ### Capture Server Logs in Subprocess Source: https://github.com/garootman/drheaderplus-mcp/blob/main/_autodocs/errors.md When running drheaderplus-mcp as a subprocess, capture its standard error stream to diagnose issues. Ensure the subprocess is started with stderr redirection. ```python import subprocess process = subprocess.Popen( ["python", "-m", "drheaderplus_mcp"], stderr=subprocess.PIPE, text=True ) # Read stderr for error messages for line in process.stderr: print(f"Server: {line}") ``` -------------------------------- ### scan_url() Source: https://github.com/garootman/drheaderplus-mcp/blob/main/_autodocs/MANIFEST.md Fetches and audits HTTP headers from a live URL. It provides details on the function signature, parameters, return structure, behavior, and error conditions, along with usage examples. ```APIDOC ## scan_url() ### Description Fetches and audits HTTP headers from a live URL. ### Signature `scan_url(url: str, preset: Optional[str] = None, include_coep_coop: bool = False) -> Dict[str, Any]` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters Table - **url** (str) - Required - The URL to scan. - **preset** (Optional[str]) - Optional - The ruleset to use for auditing. - **include_coep_coop** (bool) - Optional - Whether to include COEP/COOP checks. ### Response #### Success Response (200) - **findings** (List[Dict[str, Any]]) - A list of findings from the audit. - **url** (str) - The URL that was scanned. #### Error Response - **error** (str) - Description of the error. - **url** (str) - The URL that was attempted. ### Request Example ```python # Example usage (not actual code, conceptual) result = drheaderplus_mcp.scan_url("https://example.com", preset="default") print(result) ``` ### Response Example ```json { "url": "https://example.com", "findings": [ { "rule": "header-missing", "severity": "high", "message": "Content-Security-Policy header is missing.", "value": null } ] } ``` ``` -------------------------------- ### list_presets Tool Definition Source: https://github.com/garootman/drheaderplus-mcp/blob/main/_autodocs/mcp-protocol.md Defines the 'list_presets' tool, which retrieves a list of available ruleset presets and their descriptions. This tool has no input parameters. ```json { "name": "list_presets", "description": "List available ruleset presets and their descriptions.", "inputSchema": { "type": "object", "properties": {} } } ``` -------------------------------- ### Call Tool: scan_bulk Response (Success) Source: https://github.com/garootman/drheaderplus-mcp/blob/main/_autodocs/mcp-protocol.md Server successfully processes the 'scan_bulk' tool call, returning per-URL results and findings. ```json { "jsonrpc": "2.0", "id": 5, "result": { "content": [ { "type": "text", "text": "[{"url": "https://a.example.com", "issues": 2, "findings": [{"rule": "Content-Security-Policy", "severity": "high", "message": "Header not included in response", "value": ""}]}, {"url": "https://b.example.com", "error": "Connection refused", "findings": []}]" } ] } } ``` -------------------------------- ### Set Permissions-Policy Header in Apache Source: https://github.com/garootman/drheaderplus-mcp/blob/main/docs/security-headers-guide.md Configure Apache to set the Permissions-Policy header, restricting browser features like geolocation and camera. This example sets empty allowlists for several features. ```apache Header always set Permissions-Policy "geolocation=(), camera=(), microphone=(), payment=(), usb=()" ``` -------------------------------- ### Package Initialization Source: https://github.com/garootman/drheaderplus-mcp/blob/main/_autodocs/modules.md The initialization file for the drheaderplus_mcp package, containing only a docstring. ```python """DrHeaderPlus MCP Server.""" ``` -------------------------------- ### Set Permissions-Policy Header in Nginx Source: https://github.com/garootman/drheaderplus-mcp/blob/main/docs/security-headers-guide.md Configure Nginx to set the Permissions-Policy header, restricting browser features like geolocation and camera. This example sets empty allowlists for several features. ```nginx add_header Permissions-Policy "geolocation=(), camera=(), microphone=(), payment=(), usb=()" always; ``` -------------------------------- ### Handling Partial Failures with scan_bulk Source: https://github.com/garootman/drheaderplus-mcp/blob/main/_autodocs/tool-usage-guide.md Illustrates how to manage scenarios where some URLs in a bulk scan may fail while others succeed. It separates successful results from failures and reports accordingly. ```python results = await mcp.call_tool("scan_bulk", { "urls": [ "https://reachable.example.com", "https://unreachable.example.com", "https://another.example.com" ] }) successes = [r for r in results if "findings" in r and "error" not in r] failures = [r for r in results if "error" in r] print(f"Scanned: {len(successes)} successful, {len(failures)} failed") for result in failures: print(f"Failed to scan {result['url']}: {result['error']}") for result in successes: if result["issues"] > 0: print(f"{result['url']}: {result['issues']} issues found") ``` -------------------------------- ### Minimum Recommended Security Headers Source: https://github.com/garootman/drheaderplus-mcp/blob/main/docs/security-headers-guide.md These headers provide fundamental security protections for web applications. Ensure they are set correctly in your production environment. ```http Strict-Transport-Security: max-age=31536000; includeSubDomains Content-Security-Policy: default-src 'self' X-Content-Type-Options: nosniff X-Frame-Options: DENY Referrer-Policy: strict-origin-when-cross-origin Permissions-Policy: geolocation=(), camera=(), microphone=() ``` -------------------------------- ### Logging MCP Client Requests Source: https://github.com/garootman/drheaderplus-mcp/blob/main/_autodocs/mcp-protocol.md Example of how to log outgoing JSON-RPC requests from an MCP client using Python's logging module. Ensure the logging level is set to DEBUG to capture the sent messages. ```python import json import logging logging.basicConfig(level=logging.DEBUG) req = {"jsonrpc": "2.0", "id": 1, "method": "tools/list"} logging.debug(f"Sending: {json.dumps(req)}") ``` -------------------------------- ### Catching HTTPError in scan_url Source: https://github.com/garootman/drheaderplus-mcp/blob/main/_autodocs/errors.md This example shows how to catch HTTP errors (like 404 or 500) when scanning a single URL. Note that HTTPError might not be directly catchable and may require checking the exception string. ```python try: findings = await mcp.call_tool("scan_url", {"url": "https://example.com/notfound"}) except Exception as e: if "404" in str(e) or "500" in str(e): print(f"HTTP error: {e}") ``` -------------------------------- ### list_presets Source: https://github.com/garootman/drheaderplus-mcp/blob/main/_autodocs/mcp-protocol.md List available ruleset presets and their descriptions. This tool helps users discover which presets are available for use with other tools. ```APIDOC ## list_presets ### Description List available ruleset presets and their descriptions. ### Method JSON-RPC (via stdio) ### Parameters #### Input Schema ```json { "type": "object", "properties": {} } ``` ``` -------------------------------- ### DrHeaderPlus MCP Documentation Structure Source: https://github.com/garootman/drheaderplus-mcp/blob/main/_autodocs/README.md Visual representation of the relationship between different documentation files in the DrHeaderPlus MCP project. Each file serves a specific purpose, from overview and API reference to usage guides and error codes. ```text ┌─────────────────────────────────────────────┐ │ index.md (Overview) │ │ Quick nav, tasks, key concepts │ └────┬────────────────────────────────────┬───┘ │ │ ├──→ api-reference.md │ │ (What tools do) │ │ │ ├──→ tool-usage-guide.md │ │ (How to use tools) │ │ │ ├──→ types.md │ │ (Data structures) │ │ │ ├──→ configuration.md │ │ (How to deploy) │ │ │ ├──→ mcp-protocol.md │ │ (Wire format) │ │ │ ├──→ modules.md │ │ (Code organization) │ │ │ └──→ errors.md │ (Troubleshooting) │ │ All docs cross-link ───────────┘ ``` -------------------------------- ### Helper Function: _get_rules Source: https://github.com/garootman/drheaderplus-mcp/blob/main/_autodocs/modules.md Converts a preset name into a rules dictionary for Drheader analysis. Returns None if no preset is specified. ```python def _get_rules(preset: str | None) -> dict | None: rules = _get_rules("owasp-asvs-v14") # Returns rules dict rules = _get_rules(None) # Returns None ``` -------------------------------- ### scan_url Source: https://github.com/garootman/drheaderplus-mcp/blob/main/docs/api-reference.md Fetches headers from a URL and audits them. It sends a HEAD request to collect response headers, followed by a GET request with a probe Origin header to detect CORS misconfigurations. This is useful for a full audit including live CORS probing and cookie flag checks. ```APIDOC ## scan_url ### Description Fetches headers from a URL and audits them. Sends a HEAD request to collect response headers, then a GET request with a probe `Origin` header to detect CORS misconfigurations. ### Method POST ### Endpoint /scan_url ### Parameters #### Request Body - **url** (string) - Required - Full URL with scheme (e.g. `https://example.com`) - **preset** (string) - Optional - Ruleset preset name (see `list_presets`) - **cross_origin_isolated** (boolean) - Optional - Default: `false` - Also check COEP/COOP headers ### Response #### Success Response (200) Returns a list of findings. Empty list `[]` means all checks passed. ### Request Example ```json { "url": "https://example.com", "preset": "default", "cross_origin_isolated": false } ``` ### Response Example ```json [ { "rule": "Strict-Transport-Security", "severity": "high", "message": "max-age should be at least 31536000", "value": "max-age=100" } ] ``` ``` -------------------------------- ### Call Tool: scan_url Response (Success) Source: https://github.com/garootman/drheaderplus-mcp/blob/main/_autodocs/mcp-protocol.md Server successfully processes the 'scan_url' tool call and returns findings. ```json { "jsonrpc": "2.0", "id": 3, "result": { "content": [ { "type": "text", "text": "[{"rule": "Strict-Transport-Security", "severity": "high", "message": "Header not included in response", "value": ""}]" } ] } } ``` -------------------------------- ### Handle Potential Errors for list_presets Source: https://github.com/garootman/drheaderplus-mcp/blob/main/_autodocs/errors.md While list_presets is unlikely to fail due to no external I/O, include a try-catch block as a safety measure to handle any unexpected exceptions. ```python try: presets = await mcp.call_tool("list_presets", {}) print(f"Available presets: {list(presets.keys())}") except Exception as e: print(f"Failed to list presets: {e}") presets = {} ``` -------------------------------- ### Auditing with a Compliance Preset Source: https://github.com/garootman/drheaderplus-mcp/blob/main/_autodocs/tool-usage-guide.md Shows how to use scan_bulk with a specific compliance preset, such as 'owasp-asvs-v14', to audit a list of sites. It includes calculating a compliance score based on the total number of issues found. ```python async def audit_portfolio_for_compliance(): """Audit multiple sites against OWASP compliance rules.""" sites = [ "https://bank.example.com", "https://health-portal.example.com", "https://finance.example.com" ] results = await mcp.call_tool("scan_bulk", { "urls": sites, "preset": "owasp-asvs-v14" }) # Calculate compliance score total_issues = sum(r.get("issues", 0) for r in results if "error" not in r) total_scanned = len([r for r in results if "error" not in r]) print(f"Compliance Audit Report") print(f" Sites scanned: {total_scanned}") print(f" Total issues: {total_issues}") if total_issues == 0: print(" Status: ✓ All sites compliant!") else: print(f" Status: ⚠ {total_issues} issues to fix") return total_issues ``` -------------------------------- ### List Available Presets Source: https://github.com/garootman/drheaderplus-mcp/blob/main/docs/api-reference.md Use this snippet to retrieve a mapping of available ruleset preset names to their file paths. This is useful before specifying a `preset` parameter in other API calls. ```json { "owasp-asvs-v14": "/path/to/owasp_asvs_v14.yaml" } ``` -------------------------------- ### Audit with an Appropriately Chosen Preset Source: https://github.com/garootman/drheaderplus-mcp/blob/main/_autodocs/tool-usage-guide.md Select a security header preset based on application sensitivity, such as using a stricter preset like 'owasp-asvs-v14' for regulated applications. Falls back to a default if the specified preset is not available. ```python async def audit_with_appropriate_preset(): """Choose preset based on application sensitivity.""" presets = await mcp.call_tool("list_presets", {}) # For regulated applications, use stricter preset is_regulated = True # Set based on your application preset = "owasp-asvs-v14" if is_regulated and "owasp-asvs-v14" in presets else None findings = await mcp.call_tool("scan_url", { "url": "https://api.example.com", "preset": preset }) return findings ``` -------------------------------- ### Define CLI Entry Point Source: https://github.com/garootman/drheaderplus-mcp/blob/main/_autodocs/configuration.md Specifies the main function for the command-line interface in pyproject.toml. This allows the server to be invoked via the 'drheaderplus-mcp' command or 'python -m drheaderplus_mcp'. ```toml [project.scripts] drheaderplus-mcp = "drheaderplus_mcp.server:main" ``` -------------------------------- ### CLI Entry Point Source: https://github.com/garootman/drheaderplus-mcp/blob/main/_autodocs/modules.md The main script for running the drheaderplus-mcp package as a module via the command line. ```python from drheaderplus_mcp.server import main main() ``` -------------------------------- ### CLI Entry Point Definition Source: https://github.com/garootman/drheaderplus-mcp/blob/main/_autodocs/modules.md Defines the command-line script name 'drheaderplus-mcp' and its corresponding entry point function in the project's pyproject.toml file. ```toml [project.scripts] drheaderplus-mcp = "drheaderplus_mcp.server:main" ``` -------------------------------- ### Compare Staging vs Production Source: https://github.com/garootman/drheaderplus-mcp/blob/main/_autodocs/README.md Performs scans on multiple URLs simultaneously to compare security header findings between different environments. Useful for tracking changes and ensuring consistency. ```python results = await mcp.call_tool("scan_bulk", { "urls": ["https://staging.example.com", "https://prod.example.com"] }) for r in results: print(f"{r['url']}: {r.get('issues', '?')} issues") ``` -------------------------------- ### Basic Usage of scan_bulk Source: https://github.com/garootman/drheaderplus-mcp/blob/main/_autodocs/tool-usage-guide.md Demonstrates the fundamental use of the scan_bulk tool to audit a list of URLs. It shows how to iterate through the results and check for errors or the number of issues found per URL. ```python results = await mcp.call_tool("scan_bulk", { "urls": [ "https://api.example.com", "https://admin.example.com", "https://app.example.com" ] }) # Process results for result in results: if "error" in result: print(f"✗ {result['url']}: {result['error']}") elif result["issues"] == 0: print(f"✓ {result['url']}: Clean") else: print(f"⚠ {result['url']}: {result['issues']} issues") ``` -------------------------------- ### Presets Mapping Response Source: https://github.com/garootman/drheaderplus-mcp/blob/main/_autodocs/index.md This JSON object maps preset names to their corresponding configuration file paths. Use this to understand which preset corresponds to which configuration file. ```json { "owasp-asvs-v14": "/path/to/owasp_asvs_v14.yaml", "default": "/path/to/default.yaml" } ``` -------------------------------- ### List Available Presets Source: https://github.com/garootman/drheaderplus-mcp/blob/main/docs/troubleshooting.md Use this JSON command to list all available presets for DrHeaderPlus MCP. This helps in identifying the correct, case-sensitive preset names. ```json {"tool": "list_presets", "arguments": {}} ``` -------------------------------- ### Registering list_presets Tool Source: https://github.com/garootman/drheaderplus-mcp/blob/main/_autodocs/modules.md Registers the list_presets function as an MCP tool to retrieve available security presets. ```python @mcp.tool() def list_presets() -> dict[str, str] ``` -------------------------------- ### Validate Header Configuration Before Deployment Source: https://github.com/garootman/drheaderplus-mcp/blob/main/docs/examples.md Use `analyze_headers` to verify planned HTTP security headers before deployment. Returns an empty list if all checks pass. ```json { "tool": "analyze_headers", "arguments": { "headers": { "Strict-Transport-Security": "max-age=31536000; includeSubDomains", "Content-Security-Policy": "default-src 'self'; script-src 'self'", "X-Content-Type-Options": "nosniff", "X-Frame-Options": "DENY", "Referrer-Policy": "strict-origin-when-cross-origin", "Permissions-Policy": "geolocation=(), camera=(), microphone=()" } } } ``` -------------------------------- ### Drheaderplus-MCP Server Dependencies Source: https://github.com/garootman/drheaderplus-mcp/blob/main/_autodocs/modules.md Lists the direct and external dependencies for the drheaderplus_mcp.server module. Ensure these versions are met for proper operation. ```text drheaderplus_mcp.server ├── drheader.Drheader (Scanner class) ├── drheader.report.Finding (Finding class) ├── drheader.utils.PRESETS (Preset mappings) ├── drheader.utils.preset_rules (Preset loader) └── mcp.server.fastmcp.FastMCP (MCP server) External dependencies: - `drheaderplus>=3.0.3` — Security header audit engine - `mcp[cli]>=1.26` — MCP Python SDK ``` -------------------------------- ### list_presets Source: https://github.com/garootman/drheaderplus-mcp/blob/main/_autodocs/modules.md Retrieves a list of available security header analysis presets. This function returns a dictionary mapping preset names to their descriptions. ```APIDOC ## list_presets ### Description Retrieves a list of available security header analysis presets. This function returns a dictionary mapping preset names to their descriptions. ### Method GET ### Endpoint /list_presets ### Response #### Success Response (200) - **dict[str, str]** - A dictionary where keys are preset names and values are their descriptions. ``` -------------------------------- ### Set COEP and COOP Headers Source: https://github.com/garootman/drheaderplus-mcp/blob/main/docs/security-headers-guide.md Configure 'Cross-Origin-Embedder-Policy' and 'Cross-Origin-Opener-Policy' headers for cross-origin isolation, required for features like SharedArrayBuffer. ```nginx add_header Cross-Origin-Embedder-Policy "require-corp" always; add_header Cross-Origin-Opener-Policy "same-origin" always; ``` -------------------------------- ### Python: Fail on Any Finding Source: https://github.com/garootman/drheaderplus-mcp/blob/main/docs/ci-cd.md A Python snippet to configure CI to fail on any security header finding, regardless of severity. This is the strictest threshold. ```python # Fail on any finding exit(1 if findings else 0) ```