Skip to content

Plugins

Tool-Scan’s plugin system lets you add custom rules without modifying the core scanner. Plugins can add security threat patterns, compliance checks, and quality validators.

TypeBase classWhat it adds
SecuritySecurityRulePluginCustom threat detection patterns
ComplianceComplianceRulePluginCustom compliance checks
QualityQualityRulePluginCustom quality validators

Security plugins add regex patterns that are checked alongside built-in threat detection:

from tool_scan.plugins import SecurityRulePlugin, ThreatPatternSpec
from tool_scan.security_scanner import ThreatCategory, ThreatSeverity
class OrgSecurityRules(SecurityRulePlugin):
@property
def name(self):
return "org-security"
@property
def version(self):
return "1.0.0"
def get_threat_patterns(self):
return [
ThreatPatternSpec(
pattern=r"internal\.corp\.example",
category=ThreatCategory.DATA_EXFILTRATION,
severity=ThreatSeverity.HIGH,
title="Internal domain reference",
description="Tool references internal corporate domain",
mitigation="Remove internal domain references",
),
]

Compliance plugins add checks that validate tool definitions against custom requirements:

from tool_scan.plugins import ComplianceRulePlugin, ComplianceCheckSpec
from tool_scan.compliance_checker import ComplianceLevel, ComplianceStatus
class OrgComplianceRules(ComplianceRulePlugin):
@property
def name(self):
return "org-compliance"
@property
def version(self):
return "1.0.0"
def get_compliance_checks(self):
def check_org_prefix(tool):
name = tool.get("name", "")
if name.startswith("org_"):
return ComplianceStatus.PASS, "Tool has org prefix", None
return ComplianceStatus.FAIL, "Tool must have 'org_' prefix", "Add 'org_' prefix"
return [
ComplianceCheckSpec(
id="ORG-001",
name="Organization naming convention",
level=ComplianceLevel.RECOMMENDED,
check_fn=check_org_prefix,
),
]

Quality plugins add checks that deduct points from the quality score:

from tool_scan.plugins import QualityRulePlugin, QualityCheckSpec
class OrgQualityRules(QualityRulePlugin):
@property
def name(self):
return "org-quality"
@property
def version(self):
return "1.0.0"
def get_quality_checks(self):
def check_name_length(tool):
name = tool.get("name", "")
if len(name) > 30:
return 5.0, f"Tool name '{name}' is too long (>30 chars)"
return 0.0, None
return [
QualityCheckSpec(
id="QUAL-ORG-001",
name="Name length check",
check_fn=check_name_length,
description="Tool names should be 30 characters or fewer",
),
]

Place .py files in a directory and pass it to the CLI:

Terminal window
tool-scan --plugin-dir ./my_rules tools/*.json

All .py files in the directory (except those starting with _) are loaded automatically. Plugin classes are discovered by checking for subclasses of the base plugin types.

from tool_scan.plugins import PluginRegistry
registry = PluginRegistry()
# Load .py files from a directory
registry.load_directory("./my_rules")
# Discover pip-installed plugins via entry points
registry.discover_entry_points()
# Register a plugin instance directly
registry.register(OrgSecurityRules())

Distribute plugins as pip packages using the tool_scan.plugins entry point group:

pyproject.toml
[project.entry-points."tool_scan.plugins"]
org-security = "my_package:OrgSecurityRules"

Once installed, plugins are discovered automatically by registry.discover_entry_points() and by the CLI.

from tool_scan import MCPToolGrader
from tool_scan.plugins import PluginRegistry
registry = PluginRegistry()
registry.load_directory("./my_rules")
grader = MCPToolGrader(plugin_registry=registry)
report = grader.grade(tool)

Plugin security patterns, compliance checks, and quality checks all integrate seamlessly with the grading system. Plugin findings appear in the GradeReport.remarks list alongside built-in findings.