Analyzers¶
Core analyzers¶
mcp_zen_of_languages.analyzers.base ¶
Analyzer architecture built on Template Method and Strategy patterns.
This module is the architectural backbone of the zen analysis engine. It replaces a monolithic 400-line analyze() method with a composable pipeline of focused components, each governed by a well-known design pattern:
- Template Method (
BaseAnalyzer) defines the invariant analysis skeleton — parse → metrics → detect → result — while language subclasses override only the hooks that differ (parse_code,compute_metrics,build_pipeline). - Strategy (
ViolationDetector) encapsulates each detection algorithm behind a uniformdetect()contract, so detectors can be swapped, reordered, or shared across languages without touching the pipeline. - Context Object (
AnalysisContext) carries all intermediate state — AST, metrics, dependency graph — as a single Pydantic model, eliminating parameter explosion and giving every detector type-safe access to upstream results. - Pipeline / Chain of Responsibility (
DetectionPipeline) runs detectors sequentially, isolating failures so one broken detector never silences the rest.
Data flows through these layers as::
server / cli
→ AnalyzerFactory.create(language)
→ BaseAnalyzer.analyze(code)
→ parse_code() # Template hook
→ compute_metrics() # Template hook
→ DetectionPipeline.run()
→ ViolationDetector.detect() x N
→ _build_result()
→ AnalysisResult
Adding a new language
Subclass BaseAnalyzer, implement three hooks, and register language-specific detectors — the base class handles everything else.
Classes¶
AnalyzerConfig ¶
Bases: DetectorConfig
Baseline thresholds shared by every language analyzer.
AnalyzerConfig acts as the root configuration for the analysis engine. It inherits discriminated-union plumbing from DetectorConfig and adds the knobs that every language needs — complexity caps, length limits, and feature flags.
Language-specific subclasses (e.g. PythonAnalyzerConfig) extend this with additional fields without repeating the common ones.
| ATTRIBUTE | DESCRIPTION |
|---|---|
type | Discriminator fixed to TYPE: |
max_cyclomatic_complexity | Upper bound on average cyclomatic complexity before a violation is emitted (1-50, default 10). TYPE: |
max_nesting_depth | Maximum permitted indentation nesting depth (1-10, default 3). TYPE: |
max_function_length | Line count ceiling for a single function body (10-500, default 50). TYPE: |
max_class_length | Line count ceiling for a class definition (1-1000, default 300). TYPE: |
max_magic_methods | Allowed dunder-method count per class (0-50, default 3). TYPE: |
severity_threshold | Minimum severity a violation must reach to appear in final results (1-10, default 5). TYPE: |
enable_dependency_analysis | When TYPE: |
enable_pattern_detection | When TYPE: |
Note
Field boundaries are enforced by Pydantic ge / le constraints — passing an out-of-range value raises a ValidationError at construction time, not at analysis time.
See Also
PythonAnalyzerConfig: Python-specific extensions. BaseAnalyzer: Consumer that reads these thresholds during analysis.
PythonAnalyzerConfig ¶
Bases: AnalyzerConfig
Python-specific analyzer settings layered on top of the base defaults.
Python analysis adds checks that only make sense for CPython semantics: magic-method proliferation (__init__, __str__, …) and God Class detection. These flags let callers selectively enable or tune those detectors without affecting the shared thresholds inherited from AnalyzerConfig.
| ATTRIBUTE | DESCRIPTION |
|---|---|
detect_magic_methods | Enable the magic-method-count detector that flags classes overloading too many dunder protocols. TYPE: |
detect_god_classes | Enable the God Class detector that identifies classes with excessive responsibility. TYPE: |
max_magic_methods | Ceiling on dunder methods per class before a violation is raised (overrides the base default of 3). TYPE: |
See Also
AnalyzerConfig: Inherited base thresholds.
TypeScriptAnalyzerConfig ¶
Bases: AnalyzerConfig
TypeScript-specific analyzer settings.
TypeScript analysis extends the base thresholds with checks targeting the type system: unrestrained any usage and overly-generic type parameter lists. These flags complement — rather than replace — the complexity and length limits inherited from AnalyzerConfig.
| ATTRIBUTE | DESCRIPTION |
|---|---|
detect_any_usage | Enable detection of TYPE: |
max_type_parameters | Maximum generic type parameters allowed on a single declaration before a violation is emitted. TYPE: |
See Also
AnalyzerConfig: Inherited base thresholds.
RustAnalyzerConfig ¶
Bases: AnalyzerConfig
Rust-specific analyzer settings.
Rust analysis adds safety-oriented checks that are unique to the language's ownership model: unwrap() calls that can panic at runtime and unsafe blocks that opt out of borrow-checker guarantees. Inherits shared complexity limits from AnalyzerConfig.
| ATTRIBUTE | DESCRIPTION |
|---|---|
detect_unwrap_usage | Enable detection of TYPE: |
detect_unsafe_blocks | Enable detection of TYPE: |
See Also
AnalyzerConfig: Inherited base thresholds.
AstStatus ¶
Bases: StrEnum
Status of AST availability for the current analysis run.
AnalyzerCapabilities ¶
Bases: BaseModel
Language capability flags surfaced to analysis context and detectors.
AnalysisContext ¶
Bases: BaseModel
Type-safe state container that flows through the analysis pipeline.
AnalysisContext implements the Context Object pattern: instead of threading a growing list of positional arguments through every detector, the analyzer populates a single Pydantic model with the raw source, parsed AST, computed metrics, and cross-file metadata. Each ViolationDetector reads only the fields it needs, and the model's type annotations give IDE autocomplete for free.
The lifecycle of a context mirrors the steps inside BaseAnalyzer.analyze:
- Created with raw
codeand optionalpath. - Enriched by
parse_code()(setsast_treeandast_status). - Enriched by
compute_metrics()(setscyclomatic_summary,maintainability_index,lines_of_code). - Enriched by
_build_dependency_analysis()(setsdependency_analysis). - Consumed by each detector in the pipeline.
| ATTRIBUTE | DESCRIPTION |
|---|---|
code | Raw source text submitted for analysis. TYPE: |
path | Filesystem path associated with the source, when known. TYPE: |
language | Language identifier (e.g. TYPE: |
ast_tree | Parsed syntax tree produced by the language-specific TYPE: |
ast_status | Tri-state AST availability marker: TYPE: |
capabilities | Analyzer capability declaration used to explain which analysis surfaces are expected to be available. TYPE: |
cyclomatic_summary | Aggregated cyclomatic-complexity statistics for every block in the source. TYPE: |
maintainability_index | Halstead / McCabe maintainability score (0-100 scale). TYPE: |
lines_of_code | Physical line count of the source text. TYPE: |
dependency_analysis | Language-specific dependency graph payload, or TYPE: |
violations | Mutable list of violations accumulated during pipeline execution. TYPE: |
other_files | Sibling file contents keyed by path, enabling cross-file detectors (e.g. duplicate-code). TYPE: |
repository_imports | Per-file import index built from the wider repository, enabling coupling analysis. TYPE: |
See Also
BaseAnalyzer.analyze: Orchestrator that creates and enriches this context. ViolationDetector.detect: Consumer interface that reads context fields.
ViolationDetector ¶
Bases: ABC
Abstract base for individual violation-detection strategies.
Every concrete detector encapsulates exactly one kind of code-smell check — cyclomatic complexity, nesting depth, God Class, etc. — behind the uniform detect() contract defined here. This is the Strategy pattern: the DetectionPipeline iterates over a list of ViolationDetector instances without knowing (or caring) which algorithm each one uses.
Subclasses must implement:
detect()— inspect theAnalysisContextand return zero or moreViolationobjects.name(property) — return a human-readable identifier used in error logging.
The helper build_violation() is provided so detectors never have to manually wire up principle IDs, severity defaults, or message selection — those are resolved from the detector's own DetectorConfig.
| ATTRIBUTE | DESCRIPTION |
|---|---|
config | Per-detector configuration injected by the pipeline builder. Contains thresholds, severity, and violation message templates. TYPE: |
rule_ids | Zen rule identifiers this detector is responsible for. TYPE: |
See Also
DetectionPipeline: Runner that invokes detect() on every registered detector. AnalysisContext: Shared state read by detectors. DetectorConfig: Base configuration schema for typed detector settings.
Initialize the detector with an empty rule-ID list.
Concrete rule IDs are injected later by the pipeline builder in BaseAnalyzer.build_pipeline after matching this detector to its zen-rule definitions.
Source code in src/mcp_zen_of_languages/analyzers/base.py
Attributes¶
name abstractmethod property ¶
Human-readable identifier for this detector.
Used in log messages and error reports emitted by DetectionPipeline.run when a detector raises an unexpected exception.
| RETURNS | DESCRIPTION |
|---|---|
str | Short, unique name such as TYPE: |
str |
|
Methods:¶
detect abstractmethod ¶
Run this detector's algorithm and return any violations found.
Implementations should read only the fields they need from context (e.g. cyclomatic_summary for a complexity check) and compare against thresholds stored in config. Use build_violation to construct Violation instances with correct principle IDs and severity.
| PARAMETER | DESCRIPTION |
|---|---|
context | Pipeline state carrying parsed AST, metrics, and source text populated by earlier analysis stages. TYPE: |
config | Typed detector configuration holding thresholds, severity, and violation-message templates for this detector. TYPE: |
| RETURNS | DESCRIPTION |
|---|---|
list[Violation] | list[Violation]: Zero or more violations discovered by this strategy. An empty |
list[Violation] | list signals clean code for this detector's concern. |
Source code in src/mcp_zen_of_languages/analyzers/base.py
build_violation ¶
build_violation(
config,
*,
rule_id=None,
message=None,
contains=None,
index=0,
severity=None,
location=None,
suggestion=None,
files=None,
)
Construct a Violation from detector config with optional overrides.
This convenience factory saves every detector from repeating the same principle-ID look-up, severity resolution, and message selection logic. The algorithm is:
- Resolve
principlefromconfig.principle,config.principle_id, orconfig.type(first non-Nonewins). - If message is not given explicitly, delegate to
config.select_violation_message()using contains or index to pick the right template. - If severity is not given, fall back to
config.severityor a default of5.
| PARAMETER | DESCRIPTION |
|---|---|
config | Detector configuration carrying principle metadata, severity, and violation-message templates. TYPE: |
rule_id | Specific rule identifier for composite detectors. When provided, principle text, severity, and default message selection are resolved from that rule's preserved context. Default to None. TYPE: |
message | Explicit violation message. When TYPE: |
contains | Substring filter passed to TYPE: |
index | Zero-based position selecting one template from the config's TYPE: |
severity | Override severity score (1-10). Falls back to the config-level severity when omitted. Default to None. TYPE: |
location | Source location to attach to the violation, typically produced by TYPE: |
suggestion | Remediation hint shown alongside the violation in reports and IDE integrations. Default to None. TYPE: |
files | Related file paths included for cross-file violations such as duplicate-code detection. Default to None. TYPE: |
| RETURNS | DESCRIPTION |
|---|---|
Violation | Fully populated TYPE: |
Violation |
Source code in src/mcp_zen_of_languages/analyzers/base.py
413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 | |
DetectionPipeline ¶
Fail-safe runner that executes detectors in sequence and collects violations.
DetectionPipeline implements the Pipeline / Chain of Responsibility pattern. It owns an ordered list of ViolationDetector instances and calls each one's detect() method against the shared AnalysisContext. Violations from every detector are merged into a single flat list.
Crucially, a failure in one detector is caught and logged but never aborts the remaining detectors. This isolation guarantee means a newly added or experimental detector cannot break production analysis.
See Also
ViolationDetector: Strategy interface executed by this pipeline. BaseAnalyzer.build_pipeline: Factory that assembles the detector list from zen rules.
Prepare the pipeline with an ordered detector sequence.
| PARAMETER | DESCRIPTION |
|---|---|
detectors | Detector instances to execute, in the order they should run. Order can matter when later detectors depend on side-effects written to TYPE: |
Source code in src/mcp_zen_of_languages/analyzers/base.py
Methods:¶
run ¶
Execute every detector against the shared context and merge results.
For each detector the pipeline resolves which configuration to use: if the detector carries its own config (injected during pipeline construction), that takes precedence; otherwise the analyzer-level config is used as a fallback.
If a detector raises an exception, the error is printed and the pipeline continues with the next detector — no violations from healthy detectors are lost.
| PARAMETER | DESCRIPTION |
|---|---|
context | Shared analysis state populated by TYPE: |
config | Fallback configuration used when a detector does not carry its own per-detector config. TYPE: |
| RETURNS | DESCRIPTION |
|---|---|
list[Violation] | list[Violation]: Flat list of violations aggregated from all detectors that |
list[Violation] | executed successfully. |
Source code in src/mcp_zen_of_languages/analyzers/base.py
BaseAnalyzer ¶
Bases: ABC
Abstract skeleton for language-specific code analyzers.
BaseAnalyzer is the Template Method at the heart of the architecture. Its concrete analyze() method defines a fixed seven-step workflow — context creation → parsing → metrics → dependency analysis → detector pipeline → rules adapter → result assembly — while three abstract hooks let each language plug in its own behaviour:
| Hook | Responsibility |
|---|---|
parse_code() | Turn raw source text into a language AST |
compute_metrics() | Produce cyclomatic, maintainability, LOC |
build_pipeline() | Assemble the detector list from zen rules |
capabilities() | Declare AST/dependency/metrics support |
Subclasses such as PythonAnalyzer implement only these hooks; the invariant orchestration logic is never duplicated.
| ATTRIBUTE | DESCRIPTION |
|---|---|
config | Resolved analyzer configuration (base defaults merged with any overrides from TYPE: |
pipeline | Pre-built TYPE: |
See Also
ViolationDetector: Strategy objects executed inside the pipeline. AnalysisContext: State container flowing through every stage. AnalyzerConfig: Configuration consumed by the analyzer and its detectors.
Bootstrap the analyzer with configuration and a detector pipeline.
If no config is supplied, the language-specific default_config() hook provides sensible defaults. build_pipeline() is called immediately so the detector list is ready before the first analyze() invocation.
| PARAMETER | DESCRIPTION |
|---|---|
config | Explicit analyzer configuration. When TYPE: |
| RAISES | DESCRIPTION |
|---|---|
TypeError | If config is not |
Source code in src/mcp_zen_of_languages/analyzers/base.py
Methods:¶
default_config abstractmethod ¶
Provide the default configuration for this language.
Called by __init__ when the caller does not pass an explicit config. Language subclasses return their own typed config (e.g. PythonAnalyzerConfig) pre-populated with sensible defaults.
| RETURNS | DESCRIPTION |
|---|---|
AnalyzerConfig | Language-appropriate configuration with default thresholds. TYPE: |
Source code in src/mcp_zen_of_languages/analyzers/base.py
language abstractmethod ¶
Return the language identifier this analyzer handles.
The string must match the keys used in zen-config.yaml and the language registry (e.g. "python", "typescript", "rust").
| RETURNS | DESCRIPTION |
|---|---|
str | Lowercase language name used for rule lookup and result TYPE: |
str | tagging. |
Source code in src/mcp_zen_of_languages/analyzers/base.py
parse_code abstractmethod ¶
Parse raw source text into a language-specific syntax tree.
This is the first Template Method hook called by analyze(). Python subclasses typically delegate to the ast module; other languages may use tree-sitter or custom parsers.
| PARAMETER | DESCRIPTION |
|---|---|
code | Complete source text of the file being analyzed. TYPE: |
| RETURNS | DESCRIPTION |
|---|---|
ParserResult | None | ParserResult | None: Wrapped parse result, or |
ParserResult | None | parsed (e.g. syntax errors). A |
ParserResult | None | analysis — metric computation and detectors will proceed |
ParserResult | None | with whatever data is available. |
Source code in src/mcp_zen_of_languages/analyzers/base.py
compute_metrics abstractmethod ¶
Compute quantitative code-quality metrics for the given source.
This is the second Template Method hook. Implementations should calculate at least cyclomatic complexity, a maintainability index, and a physical line count. The returned tuple is unpacked by analyze() and stored on the AnalysisContext for downstream detectors.
| PARAMETER | DESCRIPTION |
|---|---|
code | Source text to measure. TYPE: |
ast_tree | Previously parsed syntax tree (may be TYPE: |
| RETURNS | DESCRIPTION |
|---|---|
CyclomaticSummary | None | tuple[CyclomaticSummary | None, float | None, int]: Three-element tuple of ``(cyclomatic_summary, |
float | None | maintainability_index, lines_of_code)``. Any element may be |
int |
|
Source code in src/mcp_zen_of_languages/analyzers/base.py
capabilities ¶
Declare language features supported by this analyzer implementation.
The default implementation marks all advanced capabilities as unsupported. Language analyzers with concrete parser or dependency support override this method to advertise availability.
| RETURNS | DESCRIPTION |
|---|---|
AnalyzerCapabilities | Capability flags consumed by TYPE: |
Source code in src/mcp_zen_of_languages/analyzers/base.py
analyze ¶
analyze(
code,
path=None,
other_files=None,
repository_imports=None,
*,
enable_external_tools=False,
allow_temporary_tools=False,
)
Run the full analysis workflow against a single source file.
This is the Template Method: it defines the invariant seven-step algorithm that every language analyzer follows, calling abstract hooks (parse_code, compute_metrics) and the pre-built DetectionPipeline at the appropriate moments.
Workflow steps:
- Create an
AnalysisContextfrom the inputs. - Parse source via
parse_code()→context.ast_tree. - Compute metrics via
compute_metrics()→ cyclomatic, maintainability, LOC. - (Optional) Build dependency graph →
context.dependency_analysis. - Run the detector pipeline → initial violation list.
- Merge with
RulesAdapterviolations and attachrules_summary(gracefully skipped if the adapter is unavailable). - Assemble and return the final
AnalysisResult.
| PARAMETER | DESCRIPTION |
|---|---|
code | Complete source text to analyze. TYPE: |
path | Filesystem path of the source file, used for cross-file detectors and result metadata. Default to None. TYPE: |
other_files | Map of sibling file paths to their contents, enabling detectors like duplicate-code that compare across files. Default to None. TYPE: |
repository_imports | Per-file import lists from the wider repository, enabling coupling and dependency-fan detectors. Default to None. TYPE: |
enable_external_tools | Run allow-listed external linters/tools in best-effort mode for additional diagnostics. Default to False. TYPE: |
allow_temporary_tools | Allow temporary-runner strategies (for example TYPE: |
| RETURNS | DESCRIPTION |
|---|---|
AnalysisResult | Fully populated analysis result containing metrics, TYPE: |
AnalysisResult | violations, an overall quality score, and (when available) |
AnalysisResult | a |
Source code in src/mcp_zen_of_languages/analyzers/base.py
880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 | |
build_pipeline ¶
Assemble the detector pipeline from zen rules and config overrides.
The default implementation follows a four-stage process:
- Load canonical zen rules for
self.language()viaget_language_zen(). - Project those rules into
DetectorConfiginstances using the detector registry. - Merge any overrides from
zen-config.yaml(matched by detectortype). - Instantiate each registered detector, inject its config and rule IDs, and wrap them in a
DetectionPipeline.
Language subclasses may override this method entirely to build a hand-crafted pipeline, but the rule-driven default covers most use-cases.
| RETURNS | DESCRIPTION |
|---|---|
DetectionPipeline | Ready-to-run pipeline containing all detectors registered TYPE: |
DetectionPipeline | for this language. |
| RAISES | DESCRIPTION |
|---|---|
ValueError | If no zen rules are found for the language. |
Source code in src/mcp_zen_of_languages/analyzers/base.py
1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 | |
LocationHelperMixin ¶
Reusable utilities for mapping code artefacts to source locations.
This mixin is designed to be mixed into ViolationDetector subclasses that need to pin violations to exact line/column positions. It provides two complementary strategies:
- Substring search — scan raw source text for a token and return the first matching
Location. - AST-node conversion — extract
lineno/col_offsetfrom a Python (or compatible) AST node.
See Also
ViolationDetector.build_violation: Accepts a location kwarg typically produced by these helpers.
Methods:¶
find_location_by_substring ¶
Locate the first occurrence of substring in the source text.
Scans code line-by-line and returns a one-based Location pointing to the first character of the match. When the substring is not found the method returns Location(line=1, column=1) as a safe fallback rather than raising.
| PARAMETER | DESCRIPTION |
|---|---|
code | Full source text to search, potentially multi-line. TYPE: |
substring | Token or identifier to locate (exact, case-sensitive match). TYPE: |
| RETURNS | DESCRIPTION |
|---|---|
Location | One-based TYPE: |
Location | when the substring does not appear in code. |
Source code in src/mcp_zen_of_languages/analyzers/base.py
ast_node_to_location ¶
Extract a Location from a Python-style AST node.
Reads lineno and col_offset attributes via getattr so this helper works with any AST node that exposes those fields (stdlib ast, tree-sitter adapters, etc.). Column offsets are converted from zero-based to one-based to match the Location convention.
| PARAMETER | DESCRIPTION |
|---|---|
_ast_tree | Parsed tree wrapper (currently unused but reserved for future tree-sitter adapters that need the root). TYPE: |
node | AST node expected to carry TYPE: |
| RETURNS | DESCRIPTION |
|---|---|
Location | One-based TYPE: |
Location | None | otherwise |
Source code in src/mcp_zen_of_languages/analyzers/base.py
Functions:¶
mcp_zen_of_languages.analyzers.pipeline ¶
Rule-to-config projection and pipeline override merging.
Zen principles defined in languages/*/rules.py carry metric thresholds (e.g. max_cyclomatic_complexity: 10) but detectors need typed DetectorConfig instances. This module bridges the gap with two operations:
- Projection — each principle's
metricsdict is mapped onto the config fields of every detector registered for that rule, producing a typed config per detector. - Override merging — user-supplied
zen-config.yamlpipeline entries are merged over the rule-derived defaults by matching onDetectorConfig.type, so users can tighten or relax thresholds without modifying the canonical rule definitions.
See Also
mcp_zen_of_languages.analyzers.registry — performs the actual projection and merge logic that this module delegates to.
Classes¶
PipelineConfig ¶
Bases: BaseModel
Typed container for the detector configs that drive a language pipeline.
A PipelineConfig holds an ordered list of DetectorConfig instances ready for execution by DetectionPipeline. Configs are either projected from zen principles via from_rules or loaded from zen-config.yaml and validated through the registry's discriminated-union :pyclass:TypeAdapter.
| ATTRIBUTE | DESCRIPTION |
|---|---|
language | ISO-style language identifier (e.g. TYPE: |
detectors | Ordered detector configs; validated on assignment via TYPE: |
Methods:¶
from_rules classmethod ¶
Build a complete pipeline by projecting a language's zen principles.
Loads the LanguageZenPrinciples for language, then delegates to configs_from_rules to project each principle's metrics onto the matching detector configs.
| PARAMETER | DESCRIPTION |
|---|---|
language | Language key recognised by TYPE: |
| RETURNS | DESCRIPTION |
|---|---|
PipelineConfig | A fully populated TYPE: |
PipelineConfig | all zen principles defined for the language. |
| RAISES | DESCRIPTION |
|---|---|
ValueError | If no zen rules exist for language. |
Examples:
Source code in src/mcp_zen_of_languages/analyzers/pipeline.py
Functions:¶
project_rules_to_configs ¶
Convert zen principle metric thresholds into typed detector configs.
For every ZenPrinciple in lang_zen, the function resolves which detectors are registered for that rule and maps the principle's metrics dict onto each detector's config fields. Keys that don't match any registered config field raise immediately so typos in rule definitions are caught at startup.
| PARAMETER | DESCRIPTION |
|---|---|
lang_zen | The complete set of zen principles for a single language, including metric thresholds and violation specs. TYPE: |
| RETURNS | DESCRIPTION |
|---|---|
list[DetectorConfig] | list[DetectorConfig]: Ordered detector configs with thresholds populated from the rules. |
See Also
DetectorRegistry.configs_from_rules — the registry method this function delegates to.
Source code in src/mcp_zen_of_languages/analyzers/pipeline.py
merge_pipeline_overrides ¶
Layer user overrides from zen-config.yaml onto rule-derived defaults.
Override entries are matched to base entries by DetectorConfig.type. When a match is found, only the fields explicitly set in the override are applied (via model_dump(exclude_unset=True)), preserving every rule-derived default that the user didn't touch. Overrides whose type doesn't appear in the base are appended as new detector entries.
| PARAMETER | DESCRIPTION |
|---|---|
base | Pipeline produced by TYPE: |
overrides | Pipeline section from TYPE: |
| RETURNS | DESCRIPTION |
|---|---|
PipelineConfig | A new TYPE: |
| RAISES | DESCRIPTION |
|---|---|
ValueError | If overrides.language doesn't match base.language. |
Source code in src/mcp_zen_of_languages/analyzers/pipeline.py
mcp_zen_of_languages.analyzers.analyzer_factory ¶
Factory function for creating language-specific analyzers.
Centralises the mapping from language identifiers (including common aliases like "py", "ts", "rs") to their concrete BaseAnalyzer subclass. Callers never need to import individual analyzer modules; they go through create_analyzer and receive a fully configured instance.
Framework analyzers (React, Vue, Angular, Next.js, Pydantic, FastAPI, Django, SQLAlchemy) are loaded lazily on first use to keep import-time overhead low and to avoid surfacing circular-import issues during module initialisation.
Classes¶
Functions:¶
supported_languages ¶
create_analyzer ¶
Create a language-specific analyzer instance.
Normalises language to lowercase and matches it against known identifiers and aliases. The returned analyzer has its detection pipeline pre-built from zen rules, optionally overlaid with pipeline_config overrides from zen-config.yaml.
Framework analyzers (React, Vue, Angular, etc.) are imported lazily on first use; language analyzers are imported eagerly at module load.
| PARAMETER | DESCRIPTION |
|---|---|
language | Language name or alias (case-insensitive). Common aliases are accepted — see the table below. TYPE: |
config | Global analyzer thresholds; passed through to the analyzer's TYPE: |
pipeline_config | Optional detector-level overrides merged on top of the rule-derived pipeline. Default to None. TYPE: |
| RETURNS | DESCRIPTION |
|---|---|
BaseAnalyzer | A configured TYPE: |
BaseAnalyzer | subclass ready to call |
| RAISES | DESCRIPTION |
|---|---|
ValueError | If language does not match any supported language. |
Note
Supported languages and accepted aliases:
=============================== =================================== Language Accepted identifiers =============================== =================================== Python python, py TypeScript typescript, ts, tsx JavaScript javascript, js, jsx Go go Rust rust, rs SVG svg Bash bash, sh, shell PowerShell powershell, ps, pwsh Ansible ansible, ansible-playbook Ruby ruby, rb C++ cpp, c++, cc, cxx C# csharp, cs CSS css, scss, less Docker Compose docker_compose, docker-compose Dockerfile dockerfile, docker YAML yaml, yml GitHub Actions github-actions, github_actions, gha TOML toml XML xml JSON json SQL sql, postgresql, mysql, sqlite, mssql Terraform terraform, tf Markdown / MDX markdown, mdx LaTeX latex, tex, ltx, sty, bib, bibtex =============================== ===================================
Source code in src/mcp_zen_of_languages/analyzers/analyzer_factory.py
mcp_zen_of_languages.adapters.rules_adapter ¶
Legacy bridge that adapts canonical zen principles into flat Violation models.
The RulesAdapter implements the Adapter pattern: it translates the rich ZenPrinciple / LanguageZenPrinciples hierarchy defined in rules/base_models.py into the Violation list that the original monolithic analyzer pipeline expected. New code should prefer the DetectionPipeline architecture; this adapter exists so that callers written against the old dictionary-based API continue to work without modification.
All data access uses Pydantic model attributes — never raw dictionary keys.
Classes¶
RulesAdapterConfig ¶
Bases: BaseModel
Threshold overrides that callers pass to RulesAdapter.
When a field is None the adapter falls back to the threshold embedded in the ZenPrinciple.metrics dictionary. Setting an explicit value here takes precedence, allowing project-level customisation without editing the canonical rule definitions.
| ATTRIBUTE | DESCRIPTION |
|---|---|
max_nesting_depth | Override for the maximum indentation depth before a nesting violation is emitted. TYPE: |
max_cyclomatic_complexity | Override for the cyclomatic-complexity ceiling. TYPE: |
min_maintainability_index | Override for the minimum acceptable maintainability index (Radon scale). TYPE: |
severity_threshold | Floor used by TYPE: |
RulesAdapter ¶
Legacy bridge that projects ZenPrinciple definitions onto flat Violation lists.
The adapter iterates every principle registered for a language, inspects its metrics dictionary, and applies lightweight heuristic checks (nesting depth, cyclomatic complexity, maintainability index, dependency cycles, and regex-based pattern matching). Each failed check produces a Violation that downstream reporters can render.
This class exists to preserve backward-compatibility with the pre-pipeline analysis path. New detectors should be implemented as ViolationDetector subclasses and registered via DetectionPipeline.
See Also
analyzers.pipeline.DetectionPipeline — the modern replacement. rules.base_models.ZenPrinciple — canonical principle definitions.
Bind the adapter to a language and optional threshold overrides.
Loads the LanguageZenPrinciples for language from the global ZEN_REGISTRY on construction so that subsequent find_violations calls can iterate the principle set without repeated lookups.
| PARAMETER | DESCRIPTION |
|---|---|
language | Lowercase language key (e.g. TYPE: |
config | Threshold overrides. When TYPE: |
Source code in src/mcp_zen_of_languages/adapters/rules_adapter.py
Methods:¶
find_violations ¶
find_violations(
code,
cyclomatic_summary=None,
maintainability_index=None,
dependency_analysis=None,
)
Walk every zen principle for this language and apply lightweight heuristic checks.
Each principle's metrics dictionary determines which checks fire. For example, a principle containing max_nesting_depth triggers the nesting check, while detect_circular_dependencies triggers the dependency-cycle check. Results from all principles are concatenated into a single flat list.
Note
The check pipeline runs in a fixed order for each principle: metrics extraction → nesting depth → cyclomatic complexity → maintainability index → dependency analysis → pattern matching. A check is skipped when its corresponding metric key is absent from the principle or when the required upstream data (e.g. cyclomatic_summary) is None.
| PARAMETER | DESCRIPTION |
|---|---|
code | Source code to analyse. TYPE: |
cyclomatic_summary | Pre-computed cyclomatic-complexity metrics, typically produced by TYPE: |
maintainability_index | Radon maintainability index (0-100 scale). Default to None. TYPE: |
dependency_analysis | Import-graph analysis produced by upstream dependency resolution. Default to None. TYPE: |
| RETURNS | DESCRIPTION |
|---|---|
list[Violation] | list[Violation]: All violations found across every registered |
list[Violation] | principle. |
Source code in src/mcp_zen_of_languages/adapters/rules_adapter.py
107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 | |
get_critical_violations ¶
Return only violations whose severity meets or exceeds config.severity_threshold.
| PARAMETER | DESCRIPTION |
|---|---|
violations | Full violation list, typically from TYPE: |
| RETURNS | DESCRIPTION |
|---|---|
list[Violation] | list[Violation]: Subset of violations at or above the configured |
list[Violation] | severity floor. |
Source code in src/mcp_zen_of_languages/adapters/rules_adapter.py
get_detector_config ¶
Aggregate zen-principle metrics into a single DetectorConfig.
Walks every principle for the bound language and collects thresholds, regex patterns, and metadata that match detector_name. The result lets detectors stay language-agnostic — they only consume the config shape, never raw principle objects.
| PARAMETER | DESCRIPTION |
|---|---|
detector_name | Key used to filter relevant metrics (e.g. TYPE: |
| RETURNS | DESCRIPTION |
|---|---|
DetectorConfig | A TYPE: |
DetectorConfig |
|
See Also
rules.base_models.DetectorConfig — the returned Pydantic model.
Source code in src/mcp_zen_of_languages/adapters/rules_adapter.py
summarize_violations ¶
Bucket violations into four severity bands and return per-band counts.
Bands: critical (9-10), high (7-8), medium (4-6), low (1-3).
| PARAMETER | DESCRIPTION |
|---|---|
violations | Violation list to summarise. TYPE: |
| RETURNS | DESCRIPTION |
|---|---|
dict[str, int] | dict[str, int]: Dict with keys |
dict[str, int] | mapped to integer counts. |
Source code in src/mcp_zen_of_languages/adapters/rules_adapter.py
Functions:¶
Language analyzers¶
mcp_zen_of_languages.languages.python.analyzer ¶
Python-specific analyzer built on the Template Method / Strategy architecture.
This module houses PythonAnalyzer, the reference language implementation. It plugs Python parsing (stdlib ast), radon-based metrics, and the Python detector pipeline into the shared BaseAnalyzer skeleton so that every zen-principle check runs in a deterministic, fail-safe sequence.
See Also
mcp_zen_of_languages.analyzers.base.BaseAnalyzer for the template method that orchestrates parsing → metrics → detection → result building.
Classes¶
PythonAnalyzer ¶
Bases: BaseAnalyzer, LocationHelperMixin
Analyze Python source code against zen principles.
PythonAnalyzer is the reference language implementation. It overrides the three Template Method hooks — parse_code, compute_metrics, and build_pipeline — to wire stdlib ast parsing, radon-based metrics collection, and the full suite of Python-specific violation detectors.
The analyzer also builds an import-level dependency graph so that cross-file detectors (circular dependencies, duplicate implementations, deep inheritance) can reason about the broader codebase.
| ATTRIBUTE | DESCRIPTION |
|---|---|
_pipeline_config | Optional overrides applied on top of the rule-derived detector defaults when constructing the detection pipeline.
|
Initialise the Python analyzer with optional config overrides.
| PARAMETER | DESCRIPTION |
|---|---|
config | Typed analyzer configuration controlling thresholds such as max cyclomatic complexity or nesting depth. When TYPE: |
pipeline_config | Pipeline-level overrides merged on top of the rule-derived detector defaults. Typically loaded from the TYPE: |
Source code in src/mcp_zen_of_languages/languages/python/analyzer.py
Methods:¶
default_config ¶
Return the baseline Python configuration.
These defaults are used when no explicit config is passed to the constructor. They encode the recommended thresholds for idiomatic Python code (e.g. max nesting depth of 3, max cyclomatic complexity of 10).
| RETURNS | DESCRIPTION |
|---|---|
PythonAnalyzerConfig | A fresh config instance with community-standard thresholds pre-populated. TYPE: |
Source code in src/mcp_zen_of_languages/languages/python/analyzer.py
language ¶
Return "python" as the language identifier.
This string keys into the analyzer factory and the detector registry, ensuring the correct set of detectors is loaded for Python source.
| RETURNS | DESCRIPTION |
|---|---|
str | Always TYPE: |
Source code in src/mcp_zen_of_languages/languages/python/analyzer.py
capabilities ¶
Declare Python analyzer support for AST, dependencies, and metrics.
Source code in src/mcp_zen_of_languages/languages/python/analyzer.py
parse_code ¶
Parse Python source into a ParserResult representation.
Delegates to parse_python, which already handles backend selection and returns the canonical ParserResult consumed by detectors.
| PARAMETER | DESCRIPTION |
|---|---|
code | Raw Python source text to parse. TYPE: |
| RETURNS | DESCRIPTION |
|---|---|
ParserResult | None | ParserResult | None: Parse tree, or |
Source code in src/mcp_zen_of_languages/languages/python/analyzer.py
compute_metrics ¶
Collect cyclomatic complexity, maintainability index, and line count.
Uses MetricsCollector which internally calls radon for cyclomatic complexity per function block and Halstead-based maintainability index. These metrics feed into several detectors (e.g. CyclomaticComplexityDetector, severity scaling).
| PARAMETER | DESCRIPTION |
|---|---|
code | Python source text to measure. TYPE: |
_ast_tree | Parsed syntax tree (currently unused by radon but accepted for API symmetry with other language analyzers). TYPE: |
| RETURNS | DESCRIPTION |
|---|---|
tuple[CyclomaticSummary | None, float | None, int] | tuple[CyclomaticSummary | None, float | None, int]: Three-element tuple of (cyclomatic summary, maintainability index, total lines). |
Source code in src/mcp_zen_of_languages/languages/python/analyzer.py
build_pipeline ¶
Assemble the Python detection pipeline from the detector registry.
Delegates to the base class which looks up all detectors registered for "python" in the global registry and wires them with configs derived from the active zen rules and any pipeline_config overrides.
| RETURNS | DESCRIPTION |
|---|---|
DetectionPipeline | Ordered pipeline of Python violation detectors. TYPE: |
Source code in src/mcp_zen_of_languages/languages/python/analyzer.py
mcp_zen_of_languages.languages.typescript.analyzer ¶
Language-specific analyzer implementation for typescript source files.
Classes¶
TypeScriptAnalyzer ¶
Bases: BaseAnalyzer
Analyzer for TypeScript source files focusing on type-system discipline.
TypeScript analysis is unique because the language offers an opt-in type system layered over JavaScript. Without enforcement, codebases drift toward any-heavy, loosely-typed patterns that negate TypeScript's value. This analyzer uses regex-based heuristic detectors (no TS AST parser yet) to surface anti-patterns such as any abuse, missing return types, and non-null assertion overuse.
Note
Because no tree-sitter or TypeScript compiler API parser is wired, parse_code returns None and all detectors operate on raw source text via regular expressions.
See Also
TypeScriptAnalyzerConfig for language-specific threshold defaults.
Initialize instance.
| PARAMETER | DESCRIPTION |
|---|---|
config | Typed detector or analyzer configuration that controls thresholds. Default to None. TYPE: |
pipeline_config | Optional pipeline overrides used to customize detector configuration. Default to None. TYPE: |
Source code in src/mcp_zen_of_languages/languages/typescript/analyzer.py
Methods:¶
default_config ¶
Return default analyzer configuration for this language.
| RETURNS | DESCRIPTION |
|---|---|
TypeScriptAnalyzerConfig | Default analyzer settings for the current language implementation. TYPE: |
Source code in src/mcp_zen_of_languages/languages/typescript/analyzer.py
language ¶
Return the analyzer language key.
| RETURNS | DESCRIPTION |
|---|---|
str | Identifier string consumed by callers. TYPE: |
capabilities ¶
Declare support for import/require dependency extraction.
parse_code ¶
Parse source text into a language parser result when available.
| PARAMETER | DESCRIPTION |
|---|---|
_code | Source code text being parsed or analyzed. TYPE: |
| RETURNS | DESCRIPTION |
|---|---|
ParserResult | None | ParserResult | None: Normalized parser output, or |
Source code in src/mcp_zen_of_languages/languages/typescript/analyzer.py
compute_metrics ¶
Compute complexity, maintainability, and line-count metrics.
| PARAMETER | DESCRIPTION |
|---|---|
code | Source code text being parsed or analyzed. TYPE: |
_ast_tree | Parsed syntax tree produced by the language parser, when available. TYPE: |
| RETURNS | DESCRIPTION |
|---|---|
tuple[CyclomaticSummary | None, float | None, int] | tuple[CyclomaticSummary | None, float | None, int]: Tuple containing computed metrics in analyzer-defined order. |
Source code in src/mcp_zen_of_languages/languages/typescript/analyzer.py
build_pipeline ¶
Build the detector pipeline for this analyzer.
| RETURNS | DESCRIPTION |
|---|---|
DetectionPipeline | Pipeline instance used to run configured detectors. TYPE: |
Source code in src/mcp_zen_of_languages/languages/typescript/analyzer.py
mcp_zen_of_languages.languages.rust.analyzer ¶
Language-specific analyzer implementation for rust source files.
Classes¶
RustAnalyzer ¶
Bases: BaseAnalyzer
Analyzer for Rust source files centered on ownership safety and idiomatic patterns.
Rust analysis is distinct because the language's borrow checker enforces memory safety at compile time, but developers can bypass those guarantees with unsafe blocks, unwrap() calls, and excessive clone(). This analyzer applies regex-based detectors to flag those escape hatches alongside idiomatic checks for newtype patterns, iterator preference, and standard-trait implementations.
Note
No Rust AST parser is currently wired; parse_code returns None and detectors operate on raw source text.
See Also
RustUnwrapUsageDetector, RustUnsafeBlocksDetector for the highest-impact detectors in this pipeline.
Initialize instance.
| PARAMETER | DESCRIPTION |
|---|---|
config | Typed detector or analyzer configuration that controls thresholds. Default to None. TYPE: |
pipeline_config | Optional pipeline overrides used to customize detector configuration. Default to None. TYPE: |
Source code in src/mcp_zen_of_languages/languages/rust/analyzer.py
Methods:¶
default_config ¶
Return default analyzer configuration for this language.
| RETURNS | DESCRIPTION |
|---|---|
AnalyzerConfig | Default analyzer settings for the current language implementation. TYPE: |
Source code in src/mcp_zen_of_languages/languages/rust/analyzer.py
language ¶
Return the analyzer language key.
| RETURNS | DESCRIPTION |
|---|---|
str | Identifier string consumed by callers. TYPE: |
capabilities ¶
Declare support for use/mod/extern crate dependency extraction.
parse_code ¶
Parse source text into a language parser result when available.
| PARAMETER | DESCRIPTION |
|---|---|
_code | Source code text being parsed or analyzed. TYPE: |
| RETURNS | DESCRIPTION |
|---|---|
ParserResult | None | ParserResult | None: Normalized parser output, or |
Source code in src/mcp_zen_of_languages/languages/rust/analyzer.py
compute_metrics ¶
Compute complexity, maintainability, and line-count metrics.
| PARAMETER | DESCRIPTION |
|---|---|
code | Source code text being parsed or analyzed. TYPE: |
_ast_tree | Parsed syntax tree produced by the language parser, when available. TYPE: |
| RETURNS | DESCRIPTION |
|---|---|
tuple[CyclomaticSummary | None, float | None, int] | tuple[CyclomaticSummary | None, float | None, int]: Tuple containing computed metrics in analyzer-defined order. |
Source code in src/mcp_zen_of_languages/languages/rust/analyzer.py
build_pipeline ¶
Build the detector pipeline for this analyzer.
| RETURNS | DESCRIPTION |
|---|---|
DetectionPipeline | Pipeline instance used to run configured detectors. TYPE: |