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
|
|
Functions¶
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
412 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 | |
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
Functions¶
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
Functions¶
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
879 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 | |
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
1037 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 | |
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.
Functions¶
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:
|
Functions¶
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
Functions¶
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
106 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 | |
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
Functions¶
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
Functions¶
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
Functions¶
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:
|