cisco-ai-skill-scanner 1.0.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (100) hide show
  1. cisco_ai_skill_scanner-1.0.0.dist-info/METADATA +253 -0
  2. cisco_ai_skill_scanner-1.0.0.dist-info/RECORD +100 -0
  3. cisco_ai_skill_scanner-1.0.0.dist-info/WHEEL +4 -0
  4. cisco_ai_skill_scanner-1.0.0.dist-info/entry_points.txt +4 -0
  5. cisco_ai_skill_scanner-1.0.0.dist-info/licenses/LICENSE +17 -0
  6. skillanalyzer/__init__.py +45 -0
  7. skillanalyzer/_version.py +34 -0
  8. skillanalyzer/api/__init__.py +25 -0
  9. skillanalyzer/api/api.py +34 -0
  10. skillanalyzer/api/api_cli.py +78 -0
  11. skillanalyzer/api/api_server.py +634 -0
  12. skillanalyzer/api/router.py +527 -0
  13. skillanalyzer/cli/__init__.py +25 -0
  14. skillanalyzer/cli/cli.py +816 -0
  15. skillanalyzer/config/__init__.py +26 -0
  16. skillanalyzer/config/config.py +149 -0
  17. skillanalyzer/config/config_parser.py +122 -0
  18. skillanalyzer/config/constants.py +85 -0
  19. skillanalyzer/core/__init__.py +24 -0
  20. skillanalyzer/core/analyzers/__init__.py +75 -0
  21. skillanalyzer/core/analyzers/aidefense_analyzer.py +872 -0
  22. skillanalyzer/core/analyzers/base.py +53 -0
  23. skillanalyzer/core/analyzers/behavioral/__init__.py +30 -0
  24. skillanalyzer/core/analyzers/behavioral/alignment/__init__.py +45 -0
  25. skillanalyzer/core/analyzers/behavioral/alignment/alignment_llm_client.py +240 -0
  26. skillanalyzer/core/analyzers/behavioral/alignment/alignment_orchestrator.py +216 -0
  27. skillanalyzer/core/analyzers/behavioral/alignment/alignment_prompt_builder.py +422 -0
  28. skillanalyzer/core/analyzers/behavioral/alignment/alignment_response_validator.py +136 -0
  29. skillanalyzer/core/analyzers/behavioral/alignment/threat_vulnerability_classifier.py +198 -0
  30. skillanalyzer/core/analyzers/behavioral_analyzer.py +453 -0
  31. skillanalyzer/core/analyzers/cross_skill_analyzer.py +490 -0
  32. skillanalyzer/core/analyzers/llm_analyzer.py +440 -0
  33. skillanalyzer/core/analyzers/llm_prompt_builder.py +270 -0
  34. skillanalyzer/core/analyzers/llm_provider_config.py +215 -0
  35. skillanalyzer/core/analyzers/llm_request_handler.py +284 -0
  36. skillanalyzer/core/analyzers/llm_response_parser.py +81 -0
  37. skillanalyzer/core/analyzers/meta_analyzer.py +845 -0
  38. skillanalyzer/core/analyzers/static.py +1105 -0
  39. skillanalyzer/core/analyzers/trigger_analyzer.py +341 -0
  40. skillanalyzer/core/analyzers/virustotal_analyzer.py +463 -0
  41. skillanalyzer/core/exceptions.py +77 -0
  42. skillanalyzer/core/loader.py +377 -0
  43. skillanalyzer/core/models.py +300 -0
  44. skillanalyzer/core/reporters/__init__.py +26 -0
  45. skillanalyzer/core/reporters/json_reporter.py +65 -0
  46. skillanalyzer/core/reporters/markdown_reporter.py +209 -0
  47. skillanalyzer/core/reporters/sarif_reporter.py +246 -0
  48. skillanalyzer/core/reporters/table_reporter.py +195 -0
  49. skillanalyzer/core/rules/__init__.py +19 -0
  50. skillanalyzer/core/rules/patterns.py +165 -0
  51. skillanalyzer/core/rules/yara_scanner.py +157 -0
  52. skillanalyzer/core/scanner.py +437 -0
  53. skillanalyzer/core/static_analysis/__init__.py +27 -0
  54. skillanalyzer/core/static_analysis/cfg/__init__.py +21 -0
  55. skillanalyzer/core/static_analysis/cfg/builder.py +439 -0
  56. skillanalyzer/core/static_analysis/context_extractor.py +742 -0
  57. skillanalyzer/core/static_analysis/dataflow/__init__.py +25 -0
  58. skillanalyzer/core/static_analysis/dataflow/forward_analysis.py +715 -0
  59. skillanalyzer/core/static_analysis/interprocedural/__init__.py +21 -0
  60. skillanalyzer/core/static_analysis/interprocedural/call_graph_analyzer.py +406 -0
  61. skillanalyzer/core/static_analysis/interprocedural/cross_file_analyzer.py +190 -0
  62. skillanalyzer/core/static_analysis/parser/__init__.py +21 -0
  63. skillanalyzer/core/static_analysis/parser/python_parser.py +380 -0
  64. skillanalyzer/core/static_analysis/semantic/__init__.py +28 -0
  65. skillanalyzer/core/static_analysis/semantic/name_resolver.py +206 -0
  66. skillanalyzer/core/static_analysis/semantic/type_analyzer.py +200 -0
  67. skillanalyzer/core/static_analysis/taint/__init__.py +21 -0
  68. skillanalyzer/core/static_analysis/taint/tracker.py +252 -0
  69. skillanalyzer/core/static_analysis/types/__init__.py +36 -0
  70. skillanalyzer/data/__init__.py +30 -0
  71. skillanalyzer/data/prompts/boilerplate_protection_rule_prompt.md +26 -0
  72. skillanalyzer/data/prompts/code_alignment_threat_analysis_prompt.md +901 -0
  73. skillanalyzer/data/prompts/llm_response_schema.json +71 -0
  74. skillanalyzer/data/prompts/skill_meta_analysis_prompt.md +303 -0
  75. skillanalyzer/data/prompts/skill_threat_analysis_prompt.md +263 -0
  76. skillanalyzer/data/prompts/unified_response_schema.md +97 -0
  77. skillanalyzer/data/rules/signatures.yaml +440 -0
  78. skillanalyzer/data/yara_rules/autonomy_abuse.yara +66 -0
  79. skillanalyzer/data/yara_rules/code_execution.yara +61 -0
  80. skillanalyzer/data/yara_rules/coercive_injection.yara +115 -0
  81. skillanalyzer/data/yara_rules/command_injection.yara +54 -0
  82. skillanalyzer/data/yara_rules/credential_harvesting.yara +115 -0
  83. skillanalyzer/data/yara_rules/prompt_injection.yara +71 -0
  84. skillanalyzer/data/yara_rules/script_injection.yara +83 -0
  85. skillanalyzer/data/yara_rules/skill_discovery_abuse.yara +57 -0
  86. skillanalyzer/data/yara_rules/sql_injection.yara +73 -0
  87. skillanalyzer/data/yara_rules/system_manipulation.yara +65 -0
  88. skillanalyzer/data/yara_rules/tool_chaining_abuse.yara +60 -0
  89. skillanalyzer/data/yara_rules/transitive_trust_abuse.yara +73 -0
  90. skillanalyzer/data/yara_rules/unicode_steganography.yara +65 -0
  91. skillanalyzer/hooks/__init__.py +21 -0
  92. skillanalyzer/hooks/pre_commit.py +450 -0
  93. skillanalyzer/threats/__init__.py +25 -0
  94. skillanalyzer/threats/threats.py +480 -0
  95. skillanalyzer/utils/__init__.py +28 -0
  96. skillanalyzer/utils/command_utils.py +129 -0
  97. skillanalyzer/utils/di_container.py +154 -0
  98. skillanalyzer/utils/file_utils.py +86 -0
  99. skillanalyzer/utils/logging_config.py +96 -0
  100. skillanalyzer/utils/logging_utils.py +71 -0
@@ -0,0 +1,26 @@
1
+ # Copyright 2026 Cisco Systems, Inc.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ #
15
+ # SPDX-License-Identifier: Apache-2.0
16
+
17
+ """
18
+ Configuration management for Claude Skill Analyzer.
19
+
20
+ Mirrors MCP Scanner's config structure.
21
+ """
22
+
23
+ from .config import Config
24
+ from .constants import SkillAnalyzerConstants
25
+
26
+ __all__ = ["Config", "SkillAnalyzerConstants"]
@@ -0,0 +1,149 @@
1
+ # Copyright 2026 Cisco Systems, Inc.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ #
15
+ # SPDX-License-Identifier: Apache-2.0
16
+
17
+ """
18
+ Configuration class for Claude Skill Analyzer.
19
+
20
+ Based on MCP Scanner's Config structure.
21
+ """
22
+
23
+ import os
24
+ from dataclasses import dataclass
25
+ from pathlib import Path
26
+
27
+
28
+ @dataclass
29
+ class Config:
30
+ """
31
+ Configuration for Claude Skill Analyzer.
32
+
33
+ Mirrors MCP Scanner's Config class structure.
34
+ """
35
+
36
+ # LLM Configuration
37
+ llm_provider_api_key: str | None = None
38
+ llm_model: str = "claude-3-5-sonnet-20241022"
39
+ llm_base_url: str | None = None
40
+ llm_api_version: str | None = None
41
+ llm_max_tokens: int = 4000
42
+ llm_temperature: float = 0.0
43
+ llm_rate_limit_delay: float = 2.0
44
+ llm_max_retries: int = 3
45
+ llm_timeout: int = 120
46
+
47
+ # AWS Bedrock Configuration
48
+ aws_region_name: str = "us-east-1"
49
+ aws_profile_name: str | None = None
50
+ aws_session_token: str | None = None
51
+
52
+ # Analyzer Configuration
53
+ enable_static_analyzer: bool = True
54
+ enable_llm_analyzer: bool = False
55
+ enable_behavioral_analyzer: bool = False
56
+ enable_aidefense: bool = False
57
+
58
+ # VirusTotal Configuration
59
+ virustotal_api_key: str | None = None
60
+ virustotal_upload_files: bool = False
61
+
62
+ # AI Defense Configuration
63
+ aidefense_api_key: str | None = None
64
+
65
+ # Scanning Options
66
+ max_file_size_mb: int = 10
67
+ scan_timeout_seconds: int = 300
68
+
69
+ # Output Options
70
+ output_format: str = "summary"
71
+ detailed_output: bool = False
72
+
73
+ def __post_init__(self):
74
+ """Load configuration from environment variables if not provided."""
75
+
76
+ # LLM API key from environment
77
+ if self.llm_provider_api_key is None:
78
+ self.llm_provider_api_key = os.getenv("SKILL_SCANNER_LLM_API_KEY")
79
+
80
+ # LLM model from environment (only if still at default)
81
+ if self.llm_model == "claude-3-5-sonnet-20241022":
82
+ if env_model := os.getenv("SKILL_SCANNER_LLM_MODEL"):
83
+ self.llm_model = env_model
84
+
85
+ # AWS configuration from environment
86
+ if env_region := os.getenv("AWS_REGION"):
87
+ self.aws_region_name = env_region
88
+
89
+ if env_profile := os.getenv("AWS_PROFILE"):
90
+ self.aws_profile_name = env_profile
91
+
92
+ if env_session := os.getenv("AWS_SESSION_TOKEN"):
93
+ self.aws_session_token = env_session
94
+
95
+ # Analyzer toggles from environment
96
+ if os.getenv("ENABLE_STATIC_ANALYZER", "").lower() in ("false", "0"):
97
+ self.enable_static_analyzer = False
98
+
99
+ if os.getenv("ENABLE_LLM_ANALYZER", "").lower() in ("true", "1"):
100
+ self.enable_llm_analyzer = True
101
+
102
+ if os.getenv("ENABLE_BEHAVIORAL_ANALYZER", "").lower() in ("true", "1"):
103
+ self.enable_behavioral_analyzer = True
104
+
105
+ if os.getenv("ENABLE_AIDEFENSE", "").lower() in ("true", "1"):
106
+ self.enable_aidefense = True
107
+
108
+ # VirusTotal configuration from environment
109
+ if self.virustotal_api_key is None:
110
+ self.virustotal_api_key = os.getenv("VIRUSTOTAL_API_KEY")
111
+
112
+ if os.getenv("VIRUSTOTAL_UPLOAD_FILES", "").lower() in ("true", "1"):
113
+ self.virustotal_upload_files = True
114
+
115
+ # AI Defense configuration from environment
116
+ if self.aidefense_api_key is None:
117
+ self.aidefense_api_key = os.getenv("AI_DEFENSE_API_KEY")
118
+
119
+ @classmethod
120
+ def from_env(cls) -> "Config":
121
+ """
122
+ Create configuration from environment variables.
123
+
124
+ Returns:
125
+ Config instance with values from environment
126
+ """
127
+ return cls()
128
+
129
+ @classmethod
130
+ def from_file(cls, config_file: Path) -> "Config":
131
+ """
132
+ Load configuration from .env file.
133
+
134
+ Args:
135
+ config_file: Path to .env file
136
+
137
+ Returns:
138
+ Config instance
139
+ """
140
+ # Load .env file
141
+ if config_file.exists():
142
+ with open(config_file) as f:
143
+ for line in f:
144
+ line = line.strip()
145
+ if line and not line.startswith("#") and "=" in line:
146
+ key, value = line.split("=", 1)
147
+ os.environ[key.strip()] = value.strip()
148
+
149
+ return cls.from_env()
@@ -0,0 +1,122 @@
1
+ # Copyright 2026 Cisco Systems, Inc.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ #
15
+ # SPDX-License-Identifier: Apache-2.0
16
+
17
+ """Configuration parser for Skill Analyzer.
18
+
19
+ This module provides functionality to parse configuration files
20
+ and environment variables for Skill Analyzer.
21
+ """
22
+
23
+ import os
24
+ from pathlib import Path
25
+
26
+ from ..utils.logging_config import get_logger
27
+ from .config import Config
28
+ from .constants import SkillAnalyzerConstants
29
+
30
+ logger = get_logger(__name__)
31
+
32
+
33
+ def parse_config_from_env() -> Config:
34
+ """Parse configuration from environment variables.
35
+
36
+ Returns:
37
+ Config instance with values from environment variables.
38
+ """
39
+ config = Config()
40
+
41
+ # Parse LLM configuration - use SKILL_SCANNER_* env vars only
42
+ config.llm_provider_api_key = os.getenv("SKILL_SCANNER_LLM_API_KEY")
43
+ config.llm_model = os.getenv("SKILL_SCANNER_LLM_MODEL", "claude-3-5-sonnet-20241022")
44
+
45
+ # Parse analyzer flags
46
+ if os.getenv("USE_LLM_ANALYZER", "").lower() == "true":
47
+ config.enable_llm_analyzer = True
48
+ if os.getenv("USE_BEHAVIORAL_ANALYZER", "").lower() == "true":
49
+ config.enable_behavioral_analyzer = True
50
+
51
+ # Parse output format
52
+ output_format = os.getenv("OUTPUT_FORMAT", "summary").lower()
53
+ if output_format in ["json", "markdown", "summary", "table"]:
54
+ config.output_format = output_format
55
+
56
+ # Parse verbosity
57
+ if os.getenv("VERBOSE", "").lower() == "true":
58
+ config.detailed_output = True
59
+
60
+ return config
61
+
62
+
63
+ def parse_config_file(config_path: str | None = None) -> Config:
64
+ """Parse configuration from a file.
65
+
66
+ Args:
67
+ config_path: Path to configuration file (optional).
68
+
69
+ Returns:
70
+ Config instance with values from file and environment.
71
+ """
72
+ config = parse_config_from_env()
73
+
74
+ if not config_path:
75
+ # Try to find default config file
76
+ default_paths = [
77
+ Path.home() / ".skillanalyzer" / "config.yaml",
78
+ Path.home() / ".skillanalyzer" / "config.json",
79
+ Path.cwd() / ".skillanalyzer.yaml",
80
+ Path.cwd() / ".skillanalyzer.json",
81
+ ]
82
+
83
+ for path in default_paths:
84
+ if path.exists():
85
+ config_path = str(path)
86
+ logger.debug(f"Found config file: {config_path}")
87
+ break
88
+
89
+ if config_path and Path(config_path).exists():
90
+ # For now, we'll parse environment variables
91
+ # In the future, this could parse YAML/JSON config files
92
+ logger.debug(f"Loading config from: {config_path}")
93
+ # TODO: Implement file parsing if needed
94
+
95
+ return config
96
+
97
+
98
+ class ConfigParser:
99
+ """Parser for Skill Analyzer configuration files."""
100
+
101
+ def __init__(self):
102
+ """Initialize the config parser."""
103
+ self.constants = SkillAnalyzerConstants
104
+
105
+ def parse(self, config_path: str | None = None) -> Config:
106
+ """Parse configuration from file and environment.
107
+
108
+ Args:
109
+ config_path: Optional path to configuration file.
110
+
111
+ Returns:
112
+ Parsed Config instance.
113
+ """
114
+ return parse_config_file(config_path)
115
+
116
+ def get_default_config(self) -> Config:
117
+ """Get default configuration.
118
+
119
+ Returns:
120
+ Default Config instance.
121
+ """
122
+ return Config()
@@ -0,0 +1,85 @@
1
+ # Copyright 2026 Cisco Systems, Inc.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ #
15
+ # SPDX-License-Identifier: Apache-2.0
16
+
17
+ """
18
+ Constants for Claude Skill Analyzer.
19
+
20
+ Mirrors MCP Scanner's constants structure.
21
+ """
22
+
23
+ from pathlib import Path
24
+
25
+
26
+ class SkillAnalyzerConstants:
27
+ """Constants used throughout the analyzer."""
28
+
29
+ # Version
30
+ VERSION = "0.2.0"
31
+
32
+ # Project paths
33
+ PROJECT_ROOT = Path(__file__).parent.parent.parent
34
+ PACKAGE_ROOT = Path(__file__).parent.parent
35
+
36
+ # Resource paths
37
+ DATA_DIR = PACKAGE_ROOT / "data"
38
+ PROMPTS_DIR = DATA_DIR / "prompts"
39
+ YARA_RULES_DIR = DATA_DIR / "yara_rules"
40
+ RULES_DIR = PACKAGE_ROOT / "core" / "rules"
41
+
42
+ # Default values
43
+ DEFAULT_MAX_FILE_SIZE_MB = 10
44
+ DEFAULT_SCAN_TIMEOUT = 300
45
+ DEFAULT_LLM_MODEL = "claude-3-5-sonnet-20241022"
46
+ DEFAULT_LLM_MAX_TOKENS = 4000
47
+ DEFAULT_LLM_TEMPERATURE = 0.0
48
+
49
+ # Severity levels
50
+ SEVERITY_CRITICAL = "CRITICAL"
51
+ SEVERITY_HIGH = "HIGH"
52
+ SEVERITY_MEDIUM = "MEDIUM"
53
+ SEVERITY_LOW = "LOW"
54
+ SEVERITY_INFO = "INFO"
55
+ SEVERITY_SAFE = "SAFE"
56
+
57
+ # Threat categories
58
+ THREAT_PROMPT_INJECTION = "prompt_injection"
59
+ THREAT_COMMAND_INJECTION = "command_injection"
60
+ THREAT_DATA_EXFILTRATION = "data_exfiltration"
61
+ THREAT_UNAUTHORIZED_TOOL = "unauthorized_tool_use"
62
+ THREAT_OBFUSCATION = "obfuscation"
63
+ THREAT_HARDCODED_SECRETS = "hardcoded_secrets"
64
+ THREAT_SOCIAL_ENGINEERING = "social_engineering"
65
+ THREAT_RESOURCE_ABUSE = "resource_abuse"
66
+
67
+ @classmethod
68
+ def get_prompts_path(cls) -> Path:
69
+ """Get path to prompts directory."""
70
+ return cls.PROMPTS_DIR
71
+
72
+ @classmethod
73
+ def get_rules_path(cls) -> Path:
74
+ """Get path to rules directory."""
75
+ return cls.RULES_DIR
76
+
77
+ @classmethod
78
+ def get_data_path(cls) -> Path:
79
+ """Get path to data directory."""
80
+ return cls.DATA_DIR
81
+
82
+ @classmethod
83
+ def get_yara_rules_path(cls) -> Path:
84
+ """Get path to YARA rules directory."""
85
+ return cls.YARA_RULES_DIR
@@ -0,0 +1,24 @@
1
+ # Copyright 2026 Cisco Systems, Inc.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ #
15
+ # SPDX-License-Identifier: Apache-2.0
16
+
17
+ """
18
+ Core functionality for Claude Skill Analyzer.
19
+
20
+ This module contains the core components including analyzers, scanner engine,
21
+ and data models.
22
+ """
23
+
24
+ __all__ = ["analyzers", "scanner", "loader", "models"]
@@ -0,0 +1,75 @@
1
+ # Copyright 2026 Cisco Systems, Inc.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ #
15
+ # SPDX-License-Identifier: Apache-2.0
16
+
17
+ """
18
+ Analyzer modules for detecting security vulnerabilities in Claude Skills.
19
+
20
+ Structure mirrors MCP Scanner's analyzer organization.
21
+ """
22
+
23
+ from .base import BaseAnalyzer
24
+
25
+ __all__ = ["BaseAnalyzer"]
26
+
27
+ # Import available analyzers (re-exported via __all__)
28
+ try:
29
+ from .static import StaticAnalyzer # noqa: F401
30
+
31
+ __all__.append("StaticAnalyzer")
32
+ except (ImportError, ModuleNotFoundError):
33
+ pass
34
+
35
+ try:
36
+ from .llm_analyzer import LLMAnalyzer, LLMProvider # noqa: F401
37
+
38
+ __all__.extend(["LLMAnalyzer", "LLMProvider"])
39
+ except (ImportError, ModuleNotFoundError):
40
+ pass
41
+
42
+ try:
43
+ from .behavioral_analyzer import BehavioralAnalyzer # noqa: F401
44
+
45
+ __all__.append("BehavioralAnalyzer")
46
+ except (ImportError, ModuleNotFoundError):
47
+ pass
48
+
49
+ try:
50
+ from .aidefense_analyzer import AIDefenseAnalyzer # noqa: F401
51
+
52
+ __all__.append("AIDefenseAnalyzer")
53
+ except (ImportError, ModuleNotFoundError):
54
+ pass
55
+
56
+ try:
57
+ from .trigger_analyzer import TriggerAnalyzer # noqa: F401
58
+
59
+ __all__.append("TriggerAnalyzer")
60
+ except (ImportError, ModuleNotFoundError):
61
+ pass
62
+
63
+ try:
64
+ from .cross_skill_analyzer import CrossSkillAnalyzer # noqa: F401
65
+
66
+ __all__.append("CrossSkillAnalyzer")
67
+ except (ImportError, ModuleNotFoundError):
68
+ pass
69
+
70
+ try:
71
+ from .meta_analyzer import MetaAnalysisResult, MetaAnalyzer, apply_meta_analysis_to_results # noqa: F401
72
+
73
+ __all__.extend(["MetaAnalyzer", "MetaAnalysisResult", "apply_meta_analysis_to_results"])
74
+ except (ImportError, ModuleNotFoundError):
75
+ pass