MCP (Model Context Protocol) server for the ComplianceAsCode/content project, enabling AI assistants like Claude to interact with security compliance automation workflows.
- Content Discovery: Search and explore rules, profiles, products, and templates
- Build Artifacts: Access rendered content from build directories (post-Jinja processing)
- Rule Scaffolding: Generate rule boilerplate with validation
- Control File Generation: Create control files from security policy documents
- Parse PDF, Markdown, HTML, and text policy documents
- Extract requirements with exact text preservation
- AI-powered rule mapping suggestions (requires Claude API key)
- Automatic file structure generation organized by section
- Validation and review tools
- Python 3.11+ installed
- ComplianceAsCode/content repository - Clone it first:
git clone https://github.com/ComplianceAsCode/content.git ~/workspace/content
-
Clone this repository:
git clone https://github.com/ComplianceAsCode/content-mcp.git cd content-mcp -
Install in development mode:
pip install -e ".[dev]" -
Verify installation:
content-agent --help
Add this to your Claude Desktop config file (claude_desktop_config.json):
Location of config file:
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Windows:
%APPDATA%\Claude\claude_desktop_config.json - Linux:
~/.config/Claude/claude_desktop_config.json
{
"mcpServers": {
"content-agent": {
"command": "python",
"args": ["-m", "content_agent"],
"env": {
"CONTENT_AGENT_CONTENT__REPOSITORY": "/home/user/workspace/content"
}
}
}
}Replace /home/user/workspace/content with the actual path to your ComplianceAsCode/content repository.
content-agent can automatically clone and manage the ComplianceAsCode/content repository:
{
"mcpServers": {
"content-agent": {
"command": "python",
"args": ["-m", "content_agent"],
"env": {
"CONTENT_AGENT_CONTENT__REPOSITORY": "managed",
"CONTENT_AGENT_CONTENT__MANAGED_PATH": "~/.content-agent/content"
}
}
}
}After adding the configuration:
- Restart Claude Desktop completely (quit and reopen)
- Look for a hammer icon (🔨) in the bottom right - this indicates MCP servers are loaded
- Start asking questions like "What products are available?" or "Search for SSH rules"
Run the MCP server directly from command line:
# Use existing content repository
content-agent --content-repo ~/workspace/content
# Use managed checkout (auto-clones to ~/.content-agent/content)
content-agent --content-repo managed
# With custom configuration file
content-agent --config config.yaml
# Debug mode with detailed logging
content-agent --content-repo ~/workspace/content --log-level DEBUGNote: The standalone mode runs the MCP server in stdio mode, which expects MCP protocol messages. For interactive use, integrate with Claude Desktop instead.
-
Check config file location:
- Make sure you edited the correct
claude_desktop_config.jsonfile - Verify the JSON is valid (use a JSON validator)
- Make sure you edited the correct
-
Check Claude Desktop logs:
- macOS:
~/Library/Logs/Claude/mcp*.log - Windows:
%APPDATA%\Claude\logs\mcp*.log - Linux:
~/.config/Claude/logs/mcp*.log
- macOS:
-
Verify content-agent is installed:
which content-agent python -m content_agent --help
-
Test manually:
content-agent --content-repo ~/workspace/content --log-level DEBUGYou should see initialization messages. Press Ctrl+C to exit.
Error: "Content repository not found"
- Verify the path in
CONTENT_AGENT_CONTENT__REPOSITORYexists - Use absolute paths, not relative paths
- Ensure you have read permissions
Error: "SSG modules not found"
- Make sure the content repository is complete (has
ssg/directory) - Try using a fresh clone of ComplianceAsCode/content
Error: "Permission denied"
- Check that Python and content-agent are executable
- Verify file permissions on the content repository
Add debug logging to your Claude Desktop config:
{
"mcpServers": {
"content-agent": {
"command": "python",
"args": ["-m", "content_agent"],
"env": {
"CONTENT_AGENT_CONTENT__REPOSITORY": "/home/user/workspace/content",
"CONTENT_AGENT_LOGGING__LEVEL": "DEBUG",
"CONTENT_AGENT_LOGGING__FILE": "/tmp/content-agent.log"
}
}
}
}Then check /tmp/content-agent.log for detailed error messages.
# Content repository
CONTENT_AGENT_CONTENT__REPOSITORY=/path/to/content
CONTENT_AGENT_CONTENT__BRANCH=main
# AI settings (for control file generation features)
CONTENT_AGENT_AI__ENABLED=true
CONTENT_AGENT_AI__CLAUDE_API_KEY=your_api_key_here
CONTENT_AGENT_AI__MODEL=claude-3-5-sonnet-20241022
CONTENT_AGENT_AI__MAX_TOKENS=4096
CONTENT_AGENT_AI__TEMPERATURE=0.0Create config.yaml:
content:
repository: /path/to/content
branch: main
ai:
enabled: true
claude_api_key: your_api_key_here
model: claude-3-5-sonnet-20241022
max_tokens: 4096
temperature: 0.0Run with: content-agent --config config.yaml
For full parameter details and response schemas, see the API Reference.
list_products- List all available productsget_product_details- Get product informationsearch_rules- Search rules by keyword, product, severityget_rule_details- Get complete rule information (automatically includes rendered content from builds)list_templates- List available templatesget_template_schema- Get template parameter schemalist_profiles- List profiles for a product or all productsget_profile_details- Get detailed profile information
list_built_products- List products with build artifactsget_rendered_rule- Get fully rendered rule (after Jinja processing)get_datastream_info- Get datastream information and statisticssearch_rendered_content- Search in rendered build artifacts
generate_rule_boilerplate- Generate basic rule structuregenerate_rule_from_template- Generate rule using templatevalidate_rule_yaml- Validate rule.yml structure
parse_policy_document- Parse security policy documents (PDF, Markdown, HTML, text). Optionalrequirement_idparameter filters to a single requirement section.generate_control_files- Generate control file structure from requirements (inline or directory format)validate_control_file- Validate control file syntax and structurereview_control_generation- Review generated controls with validation and suggestionslist_controls- List available control frameworks (optionalproductto scope)get_control_details- Get control framework details (optionalproductto scope)get_control_stats- Get aggregate requirement statistics for a control file (optionalproductto scope)search_control_requirements- Search within control requirements (optionalproductto scope)get_control_rule_index- Build a complete index of requirements and rule mappings across frameworks (optionalproductto scope)find_similar_requirements- Find requirements with similar text across control frameworks (optionalproductto scope)get_rule_product_availability- Check which products include a given ruleget_requirement_file_path- Resolve the filesystem path for a specific requirement (optionalproductto scope)list_unmapped_requirements- List requirements that need rule mappings (optionalproductto scope)update_requirement_rules- Update rules and status for a requirement in a control file (optionalproductto scope)
User: "Find SSH timeout rules for RHEL 9"
Claude: [calls search_rules(query="ssh timeout", product="rhel9")]
Claude: "Found 3 rules. The main one is sshd_set_idle_timeout..."
User: "Show me details"
Claude: [calls get_rule_details(rule_id="sshd_set_idle_timeout")]
Claude: "This rule checks ClientAliveInterval. I can see the source and rendered content for rhel9 and rhel10. The rendered RHEL 9 version shows ClientAliveInterval 300 (5 minutes)..."
User: "Create a new rule for SSH MaxAuthTries"
Claude: [calls generate_rule_boilerplate(...)]
Claude: "Created rule structure at linux_os/guide/services/ssh/..."
Claude: [calls validate_rule_yaml(...)]
Claude: "Rule validates successfully!"
User: "Parse this NIST 800-53 PDF and create control files"
Claude: [calls parse_policy_document(source="/path/to/nist_800_53.pdf", document_type="pdf")]
Claude: "Parsed document with 324 requirements across 18 sections..."
User: "Generate control files for these requirements"
Claude: [calls generate_control_files(policy_id="nist_800_53", ...)]
Claude: "Created control structure:
- Parent file: controls/nist_800_53.yml
- 324 requirement files in 18 sections
- Files organized: controls/nist_800_53/access_control/ac_001.yml, ..."
User: "Review the generated control files"
Claude: [calls review_control_generation(control_file_path="controls/nist_800_53.yml")]
Claude: "Review Report:
- Total requirements: 324
- Requirements with rules: 156 (48%)
- Requirements without rules: 168
- Validation: PASSED
- Suggested mappings available for 142 unmapped requirements"
┌─────────────────┐
│ Claude Desktop │
└────────┬────────┘
│ stdio
┌────────▼─────────────────────────┐
│ content-agent │
│ ┌────────────────────────────┐ │
│ │ MCP Protocol Layer │ │
│ │ - Resources, Tools, Prompts│ │
│ └────────────────────────────┘ │
│ ┌────────────────────────────┐ │
│ │ Core Business Logic │ │
│ │ - Discovery, Scaffolding │ │
│ │ - Control File Generation │ │
│ └────────────────────────────┘ │
└────────┬─────────────────────────┘
│
┌────────▼─────────────────────────┐
│ ComplianceAsCode/content │
│ - SSG modules │
└──────────────────────────────────┘
The control file generation feature enables creating ComplianceAsCode control files from security policy documents.
-
Parse Policy Document
- Supports PDF, Markdown, HTML, and plain text formats
- Extracts document structure (sections, headings)
- Preserves exact text (no AI rewording at this stage)
-
Extract Requirements (Optional, with Claude API)
- AI analyzes document to identify security requirements
- Extracts requirement text with exact wording preserved
- Associates requirements with their sections
-
Generate Control Files
- Creates individual YAML files per requirement
- Organizes files by section:
controls/<policy_id>/<section>/<req>.yml - Generates parent file with includes:
controls/<policy_id>.yml
-
AI Rule Mapping (Optional, with Claude API)
- Suggests ComplianceAsCode rules for each requirement
- Provides confidence scores and reasoning
- Classifies match types (exact_ref, keyword, semantic, description)
-
Validation and Review
- Validates YAML syntax and structure
- Checks rule references exist
- Compares extracted vs. original text
- Reports coverage statistics
Generated control files follow this structure:
controls/
├── my_policy.yml # Parent control file
└── my_policy/ # Policy directory
├── access_control/ # Section directory
│ ├── ac_001.yml # Individual requirements
│ ├── ac_002.yml
│ └── ac_003.yml
└── authentication/
├── au_001.yml
└── au_002.yml
Parent file (controls/my_policy.yml):
id: my_policy
title: My Security Policy
description: Policy description
source_document: /path/to/policy.pdf
includes:
- access_control/ac_001.yml
- access_control/ac_002.yml
- authentication/au_001.ymlRequirement file (controls/my_policy/access_control/ac_001.yml):
id: AC-1
title: Access Control Policy and Procedures
description: |
The organization develops, documents, and disseminates...
(exact text from source document)
status: automated
rules:
- file_permissions_etc_passwd
- file_ownership_etc_group
related_rules:
- accounts_password_minlen_login_defs
references:
nist:
- AC-1
notes: Implementation notes hereTo use AI-powered features (requirement extraction and rule mapping), configure Claude API access:
Via environment variables:
export CONTENT_AGENT_AI__ENABLED=true
export CONTENT_AGENT_AI__CLAUDE_API_KEY=sk-ant-...Via Claude Desktop config:
{
"mcpServers": {
"content-agent": {
"command": "python",
"args": ["-m", "content_agent"],
"env": {
"CONTENT_AGENT_CONTENT__REPOSITORY": "/path/to/content",
"CONTENT_AGENT_AI__ENABLED": "true",
"CONTENT_AGENT_AI__CLAUDE_API_KEY": "sk-ant-..."
}
}
}
}Note: AI features are optional. You can still parse documents and generate control files manually without an API key.
-
Text Preservation: The system preserves exact text from source documents. Always review extracted requirements for accuracy.
-
Section Organization: Organize requirements by logical sections matching your policy document structure.
-
Rule Mapping: AI suggestions are starting points. Review confidence scores and reasoning before accepting mappings.
-
Validation: Always run validation after generating control files to catch structural issues early.
-
Incremental Updates: You can update existing control files by adding new requirements while preserving existing mappings.
-
Clone the repository:
git clone https://github.com/ComplianceAsCode/content-mcp.git cd content-mcp -
Install development dependencies:
pip install -e ".[dev]" -
Clone the ComplianceAsCode/content repository:
git clone https://github.com/ComplianceAsCode/content.git ~/workspace/content -
Test your local installation:
# Run with local content repo content-agent --content-repo ~/workspace/content --log-level DEBUG
# Run all tests
pytest
# Run with coverage
pytest --cov=content_agent --cov-report=html
# Run specific test file
pytest tests/unit/test_config.py -v
# Run integration tests (requires content repo)
pytest tests/integration/ -v# Format code
black src/ tests/
# Lint code
ruff check src/ tests/
# Type checking
mypy src/content-agent/
├── src/content_agent/ # Main source code
│ ├── config/ # Configuration management
│ ├── core/ # Core functionality
│ │ ├── discovery/ # Content discovery (rules, products, etc.)
│ │ ├── integration/ # ComplianceAsCode integration
│ │ └── scaffolding/ # Code generation
│ ├── models/ # Pydantic data models
│ └── server/ # MCP server implementation
├── tests/ # Test suite
│ ├── unit/ # Unit tests
│ └── integration/ # Integration tests
├── examples/ # Example configurations
└── docs/ # Documentation
- Python 3.11+
- ComplianceAsCode/content repository (local or managed)
- Architecture
- API Reference
- Build Artifacts Usage - Guide to using rendered content from builds
- ComplianceAsCode Reference - Understanding ComplianceAsCode/content project structure
- Compliance Summary - Implementation compliance status
- Compliance Audit - Detailed audit report
- Build Artifacts Feature - Technical design for build artifacts support
- Unified Rule Discovery - Automatic source + rendered content in one call
Apache License 2.0 - see LICENSE file
Contributions welcome! Please see the ComplianceAsCode/content project for contribution guidelines.
This project uses OpenSpec for spec-driven development. Contributors are encouraged to use the OpenSpec workflow (/propose, /apply, /verify, /archive) when working on new features or non-trivial changes. See the OpenSpec documentation for more details. The project configuration is in openspec/config.yaml and past changes can be found in openspec/changes/archive/.
- Issues: https://github.com/ComplianceAsCode/content-mcp/issues
- Documentation: https://github.com/ComplianceAsCode/content-mcp/blob/main/README.md
- ComplianceAsCode/content: https://github.com/ComplianceAsCode/content