Content
# Cortex MCP Server Documentation
## Overview
The Cortex MCP (Model Context Protocol) Server is a Python-based integration that enables Large Language Models (LLMs) to interact with Palo Alto Networks Cortex XDR platform through standardized MCP primitives. Built on FastMCP, this server provides AI assistants with the ability to query security data, manage incidents, and perform security operations.
**Version:** 1.0.1
**Python Requirements:** 3.12 or higher
**Framework:** FastMCP 2.13.1+
**Package Manager:** uv (recommended) or Poetry (legacy support)
---
## Table of Contents
1. [Architecture](#architecture)
2. [Installation and Setup](#installation-and-setup)
3. [Resources](#1-resources)
4. [Tools](#2-tools)
5. [Prompts](#3-prompts)
6. [Authentication and Configuration](#authentication-and-configuration)
7. [Usage Examples](#usage-examples)
8. [Extending the Server](#extending-the-server)
9. [Best Practices](#best-practices)
10. [Troubleshooting](#troubleshooting)
11. [API Reference](#api-reference)
12. [Support and Resources](#support-and-resources)
---
## Architecture
### Component Structure
The Cortex MCP Server uses a modular architecture with three types of components:
1. **Builtin Components** (`src/usecase/builtin_components/`)
- Core components shipped with the package
- Contains both OpenAPI and Python modules
- Maintained by the core development team
2. **Custom Components** (`src/usecase/custom_components/`)
- User-defined components for extending functionality
- Supports both OpenAPI specifications and Python modules
- Allows organizations to add proprietary integrations
3. **Remote Components** (`src/usecase/remote_components/`)
- Components distributed and updated by Cortex
- Automatically synced via CLI `update` command
- Completely replaced on each update (do not modify)
### Key Dependencies
- **fastmcp** (2.13.1+): Core MCP server framework
- **mcp** (1.21.2+): Model Context Protocol implementation
- **fastapi** (0.122.0): Web framework for HTTP transport
- **requests** (2.32.3+): HTTP client for Cortex API calls
- **pydantic**: Data validation and serialization
- **uv**: Fast Python package installer and resolver (recommended)
---
## Installation and Setup
### Prerequisites
- Python 3.12 or higher
- Cortex API credentials (Standard API key and API key ID)
- uv package manager (recommended) or Poetry
### Installing uv (Recommended)
```bash
curl -LsSf https://astral.sh/uv/install.sh | sh
```
**Why uv?**
- 10-100x faster dependency resolution than Poetry
- Built-in lockfile support with `uv.lock`
- Compatible with standard `pyproject.toml`
- No separate installation tool required
### Setting Up the Environment
#### Option 1: Using uv (Recommended)
```bash
# Clone the repository
git clone https://github.com/okostine-panw/cortex-mcp.git
cd cortex-mcp
# Create virtual environment and install dependencies
uv venv
source .venv/bin/activate # On Windows: .venv\Scripts\activate
uv sync
```
#### Option 2: Using Poetry (Legacy)
```bash
# Install Poetry
curl -sSL https://install.python-poetry.org | python3 -
# Setup project
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
poetry install
```
### Configuring Environment Variables
Create a `.env` file for Docker deployments or configure in Claude Desktop:
```bash
CORTEX_MCP_PAPI_URL=https://api-<your-tenant>.xdr.us.paloaltonetworks.com
CORTEX_MCP_PAPI_AUTH_HEADER=<your_api_key>
CORTEX_MCP_PAPI_AUTH_ID=<your_api_key_id>
MCP_TRANSPORT=stdio # Optional, defaults to stdio
```
**Critical Note:** All three environment variables are required. Missing any will cause the server to crash with `CancelledError` after startup.
### Claude Desktop Integration
Configure in `claude_desktop_config.json`:
```json
{
"mcpServers": {
"Cortex MCP Server": {
"command": "/absolute/path/to/cortex-mcp/.venv/bin/python",
"args": [
"/absolute/path/to/cortex-mcp/src/main.py"
],
"env": {
"CORTEX_MCP_PAPI_URL": "https://api-<tenant>.xdr.us.paloaltonetworks.com",
"CORTEX_MCP_PAPI_AUTH_HEADER": "<your_api_key>",
"CORTEX_MCP_PAPI_AUTH_ID": "<your_api_key_id>",
"MCP_TRANSPORT": "stdio"
}
}
}
}
```
**Important:**
- Use absolute paths for both `command` and `args`
- Do NOT use `uvx` or relative paths (causes PATH spawn failures)
- The `.venv` directory is created by `uv venv` in project root
- Restart Claude Desktop after configuration changes
---
## 1. Resources
Resources in MCP are file-like data structures that clients can read. They provide AI assistants with contextual information about the Cortex environment.
### Resource Types
Currently, the Cortex MCP Server primarily exposes data through **tools** rather than static resources. However, the following data can be retrieved dynamically:
#### Security Incidents Resource
- **URI Pattern:** `cortex://incidents/{issue_id}`
- **Description:** Detailed information about security issues and alerts
- **MIME Type:** `application/json`
- **Access:** Retrieved via `get_issues` tool
#### Cases Resource
- **URI Pattern:** `cortex://cases/{case_id}`
- **Description:** Security investigation cases and incident records
- **MIME Type:** `application/json`
- **Access:** Retrieved via `get_cases` tool
#### Asset Inventory Resource
- **URI Pattern:** `cortex://assets/{asset_id}`
- **Description:** Information about managed endpoints and assets
- **MIME Type:** `application/json`
- **Access:** Retrieved via `get_assets` or `get_asset_by_id` tools
#### Vulnerability Database Resource
- **URI Pattern:** `cortex://vulnerabilities/{cve_id}`
- **Description:** Vulnerability information with CVSS scoring
- **MIME Type:** `application/json`
- **Access:** Retrieved via `get_vulnerabilities` tool
### Resource Access Pattern
Resources are accessed through tool calls rather than direct URI resolution. Example flow:
```
1. LLM identifies need for security data
2. LLM calls appropriate tool (e.g., get_issues)
3. Tool returns JSON response
4. LLM processes and presents information to user
```
---
## 2. Tools
Tools are functions that LLMs can call (with user approval) to perform operations in Cortex XDR. Each tool corresponds to a Cortex API endpoint.
### Tool Naming Convention
All Cortex MCP tools follow the naming pattern: `Cortex MCP Server:{tool_name}`
Example: `Cortex MCP Server:get_issues`
### 2.1 Issue Management Tools
#### `get_issues`
Retrieves security issues or alerts from the Cortex platform.
**Use Cases:**
- Security monitoring and threat detection
- Threat hunting investigations
- Security event reporting
- Real-time alert analysis
**Parameters:**
- `filters` (array, optional): Filter criteria for issues
- Example filters:
```json
[{"field": "severity", "operator": "in", "value": ["high", "critical"]}]
[{"field": "status", "operator": "in", "value": ["new", "under_investigation"]}]
[{"field": "id", "operator": "in", "value": [123]}]
```
- **Allowed fields:** `id`, `external_id`, `detection_method`, `issue_domain`, `severity`, `_insert_time`, `status`
- **Supported operators:** `"in"`, `"eq"`, `"gte"`, `"lte"`, `"contains"`
- **NOT supported:** `"neq"`, `"not_in"` (will return empty results)
- `search_from` (integer, default: 0): Pagination starting point
- `search_to` (integer, default: 30): Pagination ending point
- `sort` (object, optional): Sorting configuration
- Example: `{"field": "observation_time", "keyword": "desc"}`
- Allowed fields: `id`, `observation_time`, `severity`
**Returns:** JSON array of issue objects with detection details, severity, status, and timestamps.
**Example Usage:**
```
LLM: "Show me all critical security issues from the last 24 hours"
→ Calls get_issues with severity filter and time range
```
**Important Notes:**
- To exclude statuses, specify what you want to include instead
- Wrong: `{"field": "status", "operator": "neq", "value": "closed"}`
- Correct: `{"field": "status", "operator": "in", "value": ["new", "under_investigation", "in_progress"]}`
---
#### `get_cases`
Retrieves security investigation cases from Cortex.
**Use Cases:**
- Case management and tracking
- Historical incident analysis
- Investigation status monitoring
- Security reporting and metrics
**Parameters:**
- `filters` (array, optional): Filter criteria for cases
- Example filters:
```json
[{"field": "severity", "operator": "in", "value": ["high", "critical"]}]
[{"field": "case_domain", "operator": "in", "value": ["SECURITY"]}]
[{"field": "creation_time", "operator": "gte", "value": 1762774211000}]
```
- Allowed fields: `case_id`, `case_domain`, `severity`, `creation_time`, `status_progress`
- `search_from` (integer, default: 0): Pagination starting point
- `search_to` (integer, default: 30, max: 100): Pagination ending point
- `sort` (object, optional): Sorting configuration
- Example: `{"field": "creation_time", "keyword": "desc"}`
- Allowed fields: `id`, `severity`, `creation_time`
**Returns:** JSON array of case objects with investigation details.
**Example Usage:**
```
LLM: "What cases were created this week?"
→ Calls get_cases with creation_time filter
```
---
### 2.2 Endpoint Management Tools
#### `get_filtered_endpoints`
Retrieves filtered lists of endpoints managed by XDR agents.
**Use Cases:**
- Endpoint inventory management
- Compliance and coverage reporting
- Agent health monitoring
- Endpoint status tracking
**Parameters:**
- `request_data` (object): Contains filters, pagination, and sort options
- `filters` (array): Endpoint filter criteria
- Available filters:
- `endpoint_id_list`: List of endpoint IDs
- `endpoint_status`: `connected`, `disconnected`, `lost`, `uninstalled`
- `platform`: `windows`, `linux`, `macos`, `android`
- `dist_name`: Distribution/installation package name
- `first_seen`: When agent was first seen (timestamp)
- `last_seen`: When agent was last seen (timestamp)
- `ip_list`: IP addresses
- `public_ip_list`: Public IP addresses
- `group_name`: Agent group names
- `alias`: Alias names
- `hostname`: Host names
- `username`: Usernames
- `isolate`: Isolation status (`isolated`, `unisolated`)
- `scan_status`: Scan status values
- `search_from` (integer, default: 0): Start offset
- `search_to` (integer, default: 100): End offset
- `sort` (object): Sort configuration
- Fields: `endpoint_id`, `first_seen`, `last_seen`, `scan_status`
- Order: `ASC` or `DESC`
**Returns:** JSON array of endpoint objects with agent details.
**Example Usage:**
```
LLM: "Show me all disconnected Windows endpoints"
→ Calls get_filtered_endpoints with status and platform filters
```
---
### 2.3 Asset Management Tools
#### `get_assets`
Retrieves comprehensive asset inventory with advanced filtering.
**Use Cases:**
- Asset discovery and inventory
- Security posture assessment
- Compliance reporting
- Asset lifecycle management
**Parameters:**
- `request_data` (object, optional): Contains filtering and pagination
- `filters` (FilterGroup): Logical grouping of filter clauses
- Supports `AND` and `OR` operations
- Filter clause structure:
```json
{
"SEARCH_FIELD": "xdm.asset.type.class",
"SEARCH_TYPE": "EQ",
"SEARCH_VALUE": "WORKSTATION"
}
```
- Operators: `EQ`, `NEQ`, `GT`, `GTE`, `LT`, `LTE`, `LIKE`, `CONTAINS`, `IN`, `NOT_IN`
- `on_demand_fields` (array): Additional fields to include
- `search_from` (integer, default: 0): Start offset
- `search_to` (integer, default: 1000, max: 1000): End offset
- `sort` (array): Array of sort items with `FIELD` and `ORDER` (ASC/DESC)
**Returns:** JSON array of asset objects (maximum 1000 per request).
**Important Notes:**
- Complex OR filters often return empty results - use simpler queries
- Friendly account names/aliases are NOT searchable - use actual AWS account IDs
- Timeout issues can be resolved by reducing search parameters
**Example Usage:**
```
LLM: "Find all workstation assets in the finance department"
→ Calls get_assets with asset type and department filters
```
---
#### `get_asset_by_id`
Retrieves detailed information about a specific asset.
**Use Cases:**
- Asset detail investigation
- Configuration review
- Security context gathering
- Incident response asset analysis
**Parameters:**
- `asset_id` (string, required): Unique identifier for the asset
**Returns:** JSON object with comprehensive asset details.
**Example Usage:**
```
LLM: "Show me details for asset ID abc123"
→ Calls get_asset_by_id with the specific asset ID
```
---
### 2.4 Vulnerability Management Tools
#### `get_vulnerabilities`
Retrieves vulnerability information with CVSS scoring and distribution data.
**Use Cases:**
- Vulnerability assessment and prioritization
- Security posture monitoring
- Compliance reporting
- Patch management planning
**Parameters:**
- `filters` (array, optional): Filter criteria for vulnerabilities
- Example filters:
```json
[{"field": "cvss_severity", "operator": "eq", "value": "CRITICAL"}]
[{"field": "distribution_and_releases", "operator": "contains", "value": ["ubuntu"]}]
[{"field": "cve_id", "operator": "in", "value": ["CVE-2024-1234"]}]
```
- Available fields: `cve_id`, `cvss_severity`, `cvss_score`, `distribution_and_releases`, `package_name`
- `use_page_token` (boolean, default: false): Enable page token pagination (recommended for large datasets)
- `page_token` (string, optional): Token for fetching next page of results
- `page_size` (integer, default: 100): Number of results per page
**Returns:** JSON object with:
- `vulnerabilities`: Array of vulnerability objects
- `page_token`: Token for next page (if more results available)
- `has_more`: Boolean indicating if more pages exist
**Important Notes:**
- Vulnerabilities endpoint uses page token pagination (different from other endpoints)
- Set `use_page_token: true` for proper pagination
- Maximum page size varies by tenant configuration
- Requires Cortex Cloud Posture Management (CCSM) add-on license
**Example Usage:**
```
LLM: "Find all critical vulnerabilities in Ubuntu systems"
→ Calls get_vulnerabilities with severity and distribution filters
→ Automatically handles pagination using page tokens
```
---
### 2.5 Tenant Configuration Tools
#### `get_tenant_info`
Retrieves tenant configuration and license information.
**Use Cases:**
- License validation and entitlement checking
- Feature availability verification
- Tenant configuration auditing
- Capacity planning
**Parameters:**
- None
**Returns:** JSON object with:
- Tenant ID and name
- License entitlements
- Feature flags and capabilities
- Quota information
**Example Usage:**
```
LLM: "What features are enabled for this tenant?"
→ Calls get_tenant_info
→ Reports available features and license status
```
---
### 2.6 Assessment Profile Tools
#### `get_assessment_profile_results`
Retrieves compliance assessment results based on configured profiles.
**Use Cases:**
- Compliance monitoring and reporting
- Security baseline validation
- Gap analysis and remediation tracking
- Audit preparation
**Parameters:**
- `profile_id` (string, optional): Specific assessment profile ID
- `filters` (array, optional): Filter assessment results
- Available filters: `status`, `severity`, `compliance_label`
**Returns:** JSON array of assessment findings with:
- Assessment profile details
- Finding severity and status
- Affected resources
- Remediation guidance
- Compliance framework mappings
**Important Notes:**
- Requires Cortex Cloud Posture Management (CCSM) add-on license
- Assessment profiles must be configured in Cortex console first
**Example Usage:**
```
LLM: "Show me all failed CIS compliance checks"
→ Calls get_assessment_profile_results with compliance_label filter
```
---
## 3. Prompts
Prompts are pre-configured templates that guide LLMs through complex multi-step workflows. They combine multiple tool calls with structured analysis patterns.
### 3.1 Investigation Prompts
#### Incident Investigation Prompt
**Name:** `incident-investigation`
**Description:** Comprehensive security incident investigation workflow.
**Template:**
```
Investigate security incident:
1. Retrieve issue details and metadata
2. Identify affected endpoints and assets
3. Check for related vulnerabilities
4. Review historical cases with similar patterns
5. Provide timeline and impact assessment
6. Suggest remediation steps
```
**Tools Used:** `get_issues`, `get_cases`, `get_filtered_endpoints`, `get_assets`, `get_vulnerabilities`
**Arguments:**
- `issue_id` (required): The issue ID to investigate
- `include_similar` (boolean): Include similar historical incidents (default: true)
- `time_window` (string): Historical time window to check (default: "30d")
---
#### Threat Hunting Prompt
**Name:** `threat-hunting`
**Description:** Proactive threat hunting across environment.
**Template:**
```
Conduct threat hunting:
1. Search for indicators of compromise (IOCs)
2. Correlate across endpoints, assets, and issues
3. Identify suspicious patterns or anomalies
4. Check for known vulnerabilities being exploited
5. Provide risk assessment and recommendations
```
**Tools Used:** `get_issues`, `get_filtered_endpoints`, `get_assets`, `get_vulnerabilities`
**Arguments:**
- `iocs` (array): List of IOCs to search for
- `time_range` (string): Time period to analyze
- `asset_scope` (array): Specific asset groups to focus on
---
### 3.2 Reporting Prompts
#### Security Posture Report Prompt
**Name:** `security-posture-report`
**Description:** Comprehensive security posture assessment and reporting.
**Template:**
```
Generate security posture report:
1. Retrieve tenant license and environment info
2. Get current assessment profile results
3. Count issues by severity and status
4. List endpoint coverage by platform
5. Summarize top vulnerabilities by CVSS score
6. Provide recommendations for improvement
```
**Tools Used:** `get_tenant_info`, `get_assessment_profile_results`, `get_issues`, `get_filtered_endpoints`, `get_vulnerabilities`
**Arguments:**
- `time_period` (string): Reporting period (e.g., "last_30_days")
- `include_trends` (boolean): Include trend analysis (default: true)
---
#### Compliance Gap Analysis Prompt
**Name:** `compliance-gap-analysis`
**Description:** Identifies compliance gaps based on assessment results.
**Template:**
```
Analyze compliance gaps:
1. Retrieve assessment profile results with compliance labels
2. Filter by failed or partial assessments
3. Map findings to compliance frameworks
4. Identify affected assets and configurations
5. Prioritize remediation by compliance risk
```
**Tools Used:** `get_assessment_profile_results`, `get_assets`
**Arguments:**
- `compliance_labels` (array): Specific compliance labels to check
- `severity_threshold` (string): Minimum finding severity
---
### 3.3 Operational Prompts
#### Weekly Security Summary Prompt
**Name:** `weekly-security-summary`
**Description:** Automated weekly security operations summary.
**Template:**
```
Generate weekly security summary:
1. New issues created in last 7 days by severity
2. Cases opened, resolved, and in-progress
3. Endpoint changes (new, removed, disconnected)
4. New critical/high vulnerabilities discovered
5. Key metrics and trends
```
**Tools Used:** `get_issues`, `get_cases`, `get_filtered_endpoints`, `get_vulnerabilities`
**Arguments:**
- `days_back` (integer): Number of days to review (default: 7)
---
#### Environment Health Check Prompt
**Name:** `environment-health-check`
**Description:** Comprehensive health check of entire Cortex environment.
**Template:**
```
Perform environment health check:
1. Verify tenant license status
2. Check endpoint agent coverage and health
3. Review open high/critical issues
4. Assess vulnerability exposure (CVSS 7.0+)
5. Validate assessment profile compliance
6. Provide health score and recommendations
```
**Tools Used:** All available tools
**Arguments:**
- `critical_only` (boolean): Focus on critical items only (default: false)
---
## Authentication and Configuration
### Required Environment Variables
```bash
CORTEX_MCP_PAPI_URL=https://api-<your-tenant>.xdr.us.paloaltonetworks.com
CORTEX_MCP_PAPI_AUTH_HEADER=<your_api_key>
CORTEX_MCP_PAPI_AUTH_ID=<your_api_key_id>
MCP_TRANSPORT=stdio # or streamable-http
```
**Critical Requirements:**
- All three variables are REQUIRED
- Missing any variable causes server crash with `CancelledError`
- Use Standard API Key (not Advanced)
- Tenant URL format must match exactly
### Optional Configuration
```bash
MCP_HOST=0.0.0.0 # For streamable-http transport
MCP_PORT=8080 # For streamable-http transport
MCP_PATH=/api/v1/stream/mcp # For streamable-http transport
LOG_LEVEL=DEBUG # Enable debug logging
```
### API Credential Best Practices
1. **Never commit credentials** to version control
2. **Use .env files** for Docker deployments
3. **Use Claude Desktop env config** for local deployments
4. **Rotate API keys regularly**
5. **Monitor API usage** through Cortex dashboard
6. **Apply least privilege** - grant only necessary permissions
---
## Usage Examples
### Example 1: Security Alert Investigation
```
User: "Show me all high-severity alerts from the last 6 hours"
LLM → Calls: get_issues
Parameters: {
"filters": [
{"field": "severity", "operator": "in", "value": ["high"]},
{"field": "_insert_time", "operator": "gte", "value": <6_hours_ago>}
],
"sort": {"field": "observation_time", "keyword": "desc"}
}
LLM → Processes response and presents formatted results
```
### Example 2: Vulnerability Assessment
```
User: "Find all critical vulnerabilities in production Linux systems"
LLM → Calls: get_vulnerabilities
Parameters: {
"use_page_token": true,
"filters": [
{"field": "cvss_severity", "operator": "eq", "value": "CRITICAL"},
{"field": "distribution_and_releases", "operator": "contains", "value": ["ubuntu", "rhel", "centos"]}
]
}
LLM → Automatically handles pagination
LLM → Calls: get_assets (to correlate with production systems)
LLM → Presents integrated analysis
```
### Example 3: Endpoint Health Monitoring
```
User: "Are there any disconnected endpoints in the finance group?"
LLM → Calls: get_filtered_endpoints
Parameters: {
"request_data": {
"filters": [
{"field": "endpoint_status", "operator": "in", "value": ["disconnected"]},
{"field": "group_name", "operator": "in", "value": ["finance"]}
]
}
}
LLM → Presents list of disconnected finance endpoints with details
```
---
## Extending the Server
### Adding Custom Tools via OpenAPI
1. Create YAML file in `/custom_components/openapi/`
2. Define OpenAPI 3.0.0 specification based on Cortex API documentation
3. Remove authentication headers (handled automatically by server)
4. Server automatically discovers and loads the component
5. Test with MCP Inspector before production use
Example structure:
```yaml
openapi: 3.0.0
info:
title: Custom Cortex Tool
version: 1.0.0
paths:
/custom-endpoint:
post:
operationId: custom_operation
summary: Custom operation description
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
param1:
type: string
responses:
'200':
description: Successful response
```
### Adding Custom Tools via Python
1. Create Python module in `/custom_components/`
2. Inherit from `BaseModule` class
3. Implement required methods: `tools()`, `resources()`, `prompts()`
4. Server automatically discovers and loads the module
5. Add unit tests in `tests/` directory
Example structure:
```python
from src.pkg.base_module import BaseModule
from mcp.types import Tool
class CustomModule(BaseModule):
def tools(self) -> list[Tool]:
"""Define custom tools."""
return [
Tool(
name="custom_tool",
description="Description of what this tool does",
inputSchema={
"type": "object",
"properties": {
"param1": {"type": "string"}
},
"required": ["param1"]
}
)
]
def resources(self) -> list:
"""Define custom resources."""
return []
def prompts(self) -> list:
"""Define custom prompts."""
return []
```
### Component Locations
- **Builtin:** `src/usecase/builtin_components/` - Do not modify
- **Custom:** `src/usecase/custom_components/` - Your custom components
- **Remote:** `src/usecase/remote_components/` - Managed by Cortex (do not modify)
**Important:** Remote components are completely replaced during CLI updates. Never add custom modifications to this directory.
---
## Best Practices
### For Tool Usage
1. **Always use appropriate filters** to limit result sets and improve performance
- Use specific time ranges for time-based queries
- Filter by severity for issue/case queries
- Apply asset type filters for inventory queries
2. **Handle pagination properly** for tools that return large datasets
- Use `use_page_token: true` for vulnerabilities
- Use `search_from`/`search_to` for other endpoints
- Implement pagination logic in custom workflows
3. **Combine tools strategically** for comprehensive analysis
- Example: issues + assets + vulnerabilities for complete context
- Chain tool calls logically in workflows
- Cache intermediate results when appropriate
4. **Check tenant capabilities** before using licensed features
- Call `get_tenant_info` to verify entitlements
- Handle gracefully when features unavailable
- Inform users about license requirements
5. **Use supported operators only**
- ✅ Use: `"in"`, `"eq"`, `"gte"`, `"lte"`, `"contains"`
- ❌ Avoid: `"neq"`, `"not_in"` (will return empty results)
- To exclude values, specify what to include instead
### For Prompt Design
1. **Chain tools logically** to build comprehensive workflows
- Define clear step-by-step processes
- Handle dependencies between tool calls
- Consider failure scenarios
2. **Include error handling** in prompt templates
- Check for empty results
- Validate required data availability
- Provide meaningful error messages
3. **Provide clear output formatting** in prompt descriptions
- Specify expected output structure
- Include examples where helpful
- Consider user experience
4. **Make arguments optional** with sensible defaults
- Provide default values for common parameters
- Document required vs optional arguments
- Validate input before processing
### For Custom Components
1. **Use OpenAPI for simple integrations** without complex logic
- Best for straightforward API endpoint mappings
- Easier to maintain and update
- No Python coding required
2. **Use Python modules for advanced workflows** requiring state management
- Complex business logic
- State management between calls
- Custom error handling
- Data transformation
3. **Never modify remote_components/** as they're overwritten on updates
- All changes will be lost during CLI update
- Use custom_components/ instead
- Document any customizations
4. **Add end-to-end tests** in `tests/e2e/` for custom components
- Test integration with MCP server
- Validate tool inputs and outputs
- Test error conditions
### For Security
1. **Protect API credentials** - never hardcode in components
- Use environment variables
- Never commit credentials to git
- Rotate keys regularly
2. **Use principle of least privilege** for API keys
- Create dedicated keys for MCP server
- Grant only necessary permissions
- Monitor key usage
3. **Validate and sanitize inputs** in custom Python modules
- Validate data types and formats
- Sanitize user inputs
- Prevent injection attacks
4. **Log security-relevant actions** for audit trails
- Log API calls with parameters
- Track privileged operations
- Review logs regularly
### For API Interactions
1. **Respect rate limits**
- Implement exponential backoff
- Batch requests where possible
- Cache frequently accessed data
2. **Handle timeouts gracefully**
- Reduce search parameters for large queries
- Use pagination for extensive datasets
- Implement retry logic with backoff
3. **Simplify complex filters**
- Break OR conditions into multiple queries
- Combine results in application layer
- Test filter combinations before deployment
4. **Use actual IDs, not friendly names**
- AWS account IDs, not account names
- Endpoint IDs, not hostnames (when filtering)
- Maintain local mapping if needed
---
## Troubleshooting
### Common Issues and Solutions
#### Issue: Server Crashes with CancelledError
**Symptoms:**
```
INFO - Starting MCP server...
INFO - MCP server started successfully
ERROR - Server error: CancelledError
ERROR - Server shutdown error: CancelledError
```
**Root Cause:** Missing required environment variables in Claude Desktop configuration.
**Solution:**
1. Open `claude_desktop_config.json`
2. Verify ALL THREE environment variables are present:
```json
"env": {
"CORTEX_MCP_PAPI_URL": "https://api-<tenant>.xdr.us.paloaltonetworks.com",
"CORTEX_MCP_PAPI_AUTH_HEADER": "<your_api_key>",
"CORTEX_MCP_PAPI_AUTH_ID": "<your_api_key_id>"
}
```
3. Add any missing variables
4. Restart Claude Desktop
**Prevention:** Always validate configuration before restarting Claude Desktop.
---
#### Issue: PATH-related Spawn Failures
**Symptoms:**
```
Error: spawn uvx ENOENT
Error: Command not found
```
**Root Cause:** Claude Desktop cannot resolve commands in user's PATH.
**Solution:** Use absolute path to Python interpreter:
❌ **Don't use:**
```json
"command": "uvx",
"args": ["--from", "cortex-mcp", "cortex-mcp"]
```
✅ **Do use:**
```json
"command": "/absolute/path/to/cortex-mcp/.venv/bin/python",
"args": ["/absolute/path/to/cortex-mcp/src/main.py"]
```
**Prevention:** Always use absolute paths in Claude Desktop configuration.
---
#### Issue: Empty Results from API Calls
**Symptoms:**
- Tools return empty arrays `[]`
- No data despite knowing records exist
- Successful API calls but no results
**Root Causes and Solutions:**
1. **Using unsupported operators**
❌ **Wrong:**
```json
{"field": "status", "operator": "neq", "value": "closed"}
```
✅ **Correct:**
```json
{"field": "status", "operator": "in", "value": ["new", "under_investigation"]}
```
2. **Complex OR filters**
- Cortex APIs struggle with complex OR conditions
- **Solution:** Break into multiple simpler queries
- Combine results in application layer
3. **Timeout issues**
- Large queries can timeout
- **Solution:** Reduce filter parameters
- Use pagination for large result sets
- Narrow time ranges for time-based queries
4. **Account name searching**
- Friendly account names/aliases are NOT searchable
- **Solution:** Use actual AWS account IDs
- Maintain local mapping of names to IDs
**Debug Steps:**
1. Enable debug logging: `export LOG_LEVEL=DEBUG`
2. Check exact filter syntax
3. Simplify query to identify problem
4. Verify API permissions
5. Test with known existing data
---
#### Issue: Package Import Errors
**Symptoms:**
```python
importlib.metadata.PackageNotFoundError: No package metadata was found for CortexMCP
```
**Root Cause:** Mismatch between package name in `pyproject.toml` and code.
**Solution:**
- Ensure consistency:
- In `pyproject.toml`: `name = "CortexMCP"`
- In code: `importlib.metadata.version("CortexMCP")`
- Names must match exactly (case-sensitive)
---
#### Issue: Custom Components Not Loading
**Symptoms:**
- Custom tools don't appear in available tools list
- No errors in logs
**Diagnostic Steps:**
1. **Verify file location:**
```bash
# YAML components
src/usecase/custom_components/openapi/your_component.yaml
# Python components
src/usecase/custom_components/your_module.py
```
2. **Check YAML syntax:**
```bash
python -c "import yaml; yaml.safe_load(open('your_component.yaml'))"
```
3. **Verify Python module structure:**
- Must inherit from `BaseModule`
- Must implement `tools()`, `resources()`, `prompts()` methods
- Check syntax: `python -m py_compile your_module.py`
4. **Enable debug logging:**
```bash
export LOG_LEVEL=DEBUG
python src/main.py
```
5. **Check for import errors:**
```bash
python -c "from src.usecase.custom_components.your_module import YourModule"
```
---
#### Issue: Pagination Not Working for Vulnerabilities
**Symptoms:**
- Pagination returns same results
- Missing results in large datasets
**Solution:**
- Ensure `use_page_token: true` is set
- Use returned `page_token` for subsequent requests
- Check for `has_more` indicator
**Correct usage:**
```python
# First request
{
"use_page_token": true,
"page_size": 100
}
# Subsequent requests
{
"use_page_token": true,
"page_token": "<token_from_previous_response>",
"page_size": 100
}
```
---
### Debug Tools and Techniques
#### Enable Debug Logging
```bash
export LOG_LEVEL=DEBUG
python src/main.py
```
#### MCP Inspector
Best tool for debugging MCP servers:
```bash
# Install
npx @modelcontextprotocol/inspector
# Run with server
npx @modelcontextprotocol/inspector uv run python src/main.py
```
#### End-to-End Tests
```bash
# Run all tests
uv run pytest
# Run specific test
uv run pytest tests/e2e/test_issues.py
# Run with verbose output
uv run pytest -v
# Run with debug output
uv run pytest -v --log-cli-level=DEBUG
```
#### Validate Component Syntax
```bash
# YAML components
python -c "import yaml; print(yaml.safe_load(open('component.yaml')))"
# Python components
python -m py_compile your_module.py
```
---
## API Reference
### Filter Operators
#### Supported Operators
| Operator | Description | Use Case |
|----------|-------------|----------|
| `"in"` | Value in list | Most common, filtering by multiple values |
| `"eq"` | Exact match | Single value matches |
| `"gte"` | Greater than or equal | Timestamps, numeric values |
| `"lte"` | Less than or equal | Timestamps, numeric values |
| `"contains"` | Array contains value | For array/list fields |
#### NOT Supported Operators
| Operator | Status | Alternative |
|----------|--------|-------------|
| `"neq"` | ❌ NOT SUPPORTED | Use `"in"` with values to include |
| `"not_in"` | ❌ NOT SUPPORTED | Use `"in"` with values to include |
### Filter Syntax Examples
```python
# Filter by severity (multiple values)
{"field": "severity", "operator": "in", "value": ["high", "critical"]}
# Filter by time range
{"field": "_insert_time", "operator": "gte", "value": "2024-01-01T00:00:00Z"}
# Filter by multiple statuses
{"field": "status", "operator": "in", "value": ["new", "under_investigation"]}
# Filter by single ID
{"field": "id", "operator": "in", "value": [123]}
# To exclude a status (specify what to include instead)
# Wrong: {"field": "status", "operator": "neq", "value": "closed"}
# Right: {"field": "status", "operator": "in", "value": ["new", "under_investigation", "in_progress"]}
```
### Pagination Strategies
#### Standard Endpoints (Issues, Cases, Endpoints)
```python
{
"search_from": 0,
"search_to": 100
}
```
#### Vulnerabilities Endpoint
```python
# First request
{
"use_page_token": true,
"page_size": 100
}
# Subsequent requests
{
"use_page_token": true,
"page_token": "<token_from_previous_response>",
"page_size": 100
}
```
### Rate Limiting
Cortex APIs enforce rate limits per tenant:
- Limits vary by endpoint and license type
- Implement exponential backoff for rate limit errors
- Consider caching frequently accessed data
- Batch requests where possible
**Exponential Backoff Example:**
```python
import time
def call_with_backoff(func, max_retries=3):
for attempt in range(max_retries):
try:
return func()
except RateLimitError:
if attempt < max_retries - 1:
sleep_time = 2 ** attempt
time.sleep(sleep_time)
else:
raise
```
### Timeout Handling
**Common timeout scenarios:**
1. Large date ranges in time-based filters
2. Complex queries with many filter conditions
3. Requests for all data without pagination
**Solutions:**
- Narrow time windows for time-based queries
- Simplify complex filters
- Always use pagination for large datasets
- Set reasonable limits on result set sizes
---
## Development Workflow
### Common Commands
#### Using uv (Recommended)
```bash
# Install dependencies
uv sync
# Add new dependency
uv add <package-name>
# Add dev dependency
uv add --dev <package-name>
# Run tests
uv run pytest
# Format code
uv run black .
uv run ruff check --fix .
# Type checking
uv run mypy src/
# Run server
uv run python src/main.py
# Run CLI
uv run python src/cli.py --help
```
#### Using Poetry (Legacy)
```bash
# Install dependencies
poetry install
# Add new dependency
poetry add <package-name>
# Run tests
poetry run pytest
# Format code
poetry run black .
poetry run isort .
```
### Pre-commit Hooks
```bash
# Install pre-commit
uv run pre-commit install
# Run hooks manually
uv run pre-commit run --all-files
```
### Version Compatibility Matrix
| Component | Version | Status | Notes |
|-----------|---------|--------|-------|
| Python | 3.12+ | Required | Minimum version |
| Python | 3.13+ | Supported | Recommended |
| fastmcp | 2.13.1+ | Required | Core framework |
| mcp | 1.21.2+ | Required | Protocol implementation |
| uv | Latest | Recommended | Fast package manager |
| Poetry | 1.8+ | Legacy | Still supported |
| Docker | 20.10+ | Optional | For containerization |
---
## Support and Resources
### Documentation
- **Main README:** [README.md](README.md) - Quick start guide
- **This Document:** Comprehensive API and usage reference
- **Troubleshooting Guide:** [TROUBLESHOOTING_QUICK_REFERENCE.md](TROUBLESHOOTING_QUICK_REFERENCE.md)
### External Resources
- **Cortex API Documentation:** https://docs-cortex.paloaltonetworks.com/
- **MCP Protocol Specification:** https://modelcontextprotocol.io/
- **FastMCP Documentation:** https://gofastmcp.com/
- **uv Documentation:** https://docs.astral.sh/uv/
- **GitHub Repository:** https://github.com/okostine-panw/cortex-mcp
### Getting Help
**For Cortex MCP Server issues:**
- GitHub Issues: https://github.com/okostine-panw/cortex-mcp/issues
- Include: Error messages, configuration (sanitized), steps to reproduce
- Check troubleshooting guide first
**For Cortex API issues:**
- Palo Alto Networks Support Portal
- Include: API endpoint, request/response, tenant ID
**For MCP Protocol questions:**
- MCP GitHub: https://github.com/modelcontextprotocol
- MCP Discord Community
---
## Version History
### 1.0.1 - Current Version
**Features:**
- Complete tool suite for issues, cases, endpoints, assets, vulnerabilities
- Assessment profile support with compliance mappings
- Tenant configuration tools
- Extensible component architecture (builtin, custom, remote)
- 250+ Cortex Cloud API endpoints supported
**Infrastructure:**
- Migrated from Poetry to uv for dependency management
- Improved installation and setup process
- Enhanced debugging capabilities
- Comprehensive error handling
**Documentation:**
- Complete API reference
- Troubleshooting guide with common issues
- Usage examples and best practices
- Development workflow documentation
---
## License Requirements
Certain features require specific Cortex licenses:
- **Vulnerabilities Management:** Requires Cortex Cloud Posture Management (CCSM) add-on
- **Assessment Profiles:** Requires Cortex Cloud Posture Management (CCSM) add-on
**Verify entitlements:**
```
Use get_tenant_info tool to check available features and licenses
```
---
## Migration Guide: Poetry to uv
For existing installations using Poetry:
### Step 1: Install uv
```bash
curl -LsSf https://astral.sh/uv/install.sh | sh
```
### Step 2: Create New Virtual Environment
```bash
# Your pyproject.toml is already compatible - no changes needed
uv venv
source .venv/bin/activate # On Windows: .venv\Scripts\activate
```
### Step 3: Install Dependencies
```bash
uv sync
```
### Step 4: Update Claude Desktop Configuration
Change virtual environment path:
```json
{
"mcpServers": {
"Cortex MCP Server": {
"command": "/absolute/path/to/cortex-mcp/.venv/bin/python",
"args": ["/absolute/path/to/cortex-mcp/src/main.py"],
"env": { ... }
}
}
}
```
Note: Changed from `venv/bin/python` to `.venv/bin/python`
### Step 5: Verify Installation
```bash
uv run python src/main.py --version
```
### Step 6: Optional Cleanup
```bash
# Remove old Poetry artifacts
rm -rf poetry.lock
rm -rf venv/ # Old Poetry virtual environment
```
---
## Quick Reference
### Most Common Issues
1. **Server crashes with CancelledError** → Check all three environment variables are set
2. **Empty API results** → Use `"in"` operator, not `"neq"`
3. **PATH spawn failures** → Use absolute paths in Claude Desktop config
4. **Custom components not loading** → Check file location and syntax
5. **Package import errors** → Verify package name consistency
### Essential Commands
```bash
# Setup
uv venv && uv sync
# Run server
uv run python src/main.py
# Debug with Inspector
npx @modelcontextprotocol/inspector uv run python src/main.py
# Run tests
uv run pytest
# Format code
uv run black . && uv run ruff check --fix .
```
### Required Environment Variables
```bash
CORTEX_MCP_PAPI_URL=https://api-<tenant>.xdr.us.paloaltonetworks.com
CORTEX_MCP_PAPI_AUTH_HEADER=<your_api_key>
CORTEX_MCP_PAPI_AUTH_ID=<your_api_key_id>
```
---
**End of Documentation**
For the latest updates and additional resources, visit:
https://github.com/okostine-panw/cortex-mcp
MCP Config
Below is the configuration for this MCP Server. You can copy it directly to Cursor or other MCP clients.
mcp.json
Connection Info
You Might Also Like
cc-switch
All-in-One Assistant for Claude Code, Codex & Gemini CLI across platforms.
awesome-claude-skills
A curated list of awesome Claude Skills, resources, and tools for...
claude-flow
Claude-Flow v2.7.0 is an enterprise AI orchestration platform.
Appwrite
Build like a team of hundreds
semantic-kernel
Build and deploy intelligent AI agents with Semantic Kernel's orchestration...
Anthropic-Cybersecurity-Skills
734+ structured cybersecurity skills for AI agents · MITRE ATT&CK mapped ·...