Skip to main content
Glama
CodeHealth MCP Server

CodeHealth MCP Server

codehealth-mcp

Maintainability scoring for AI coding agents. CodeHealth scores source files from 1 to 10 (Healthy >= 9, Warning >= 4, Alert < 4), lists code smells with the function, line range, measured value, threshold and a fix hint, and gates commits and pull requests on whether touched code got worse. It runs as an MCP server for Claude Code, Claude Desktop, Codex, Cursor, VS Code and Kiro, and as a CLI.

It reads about 30 languages through lizard (per-function metrics), adds tree-sitter analysis for Python, JavaScript, TypeScript/TSX, Java and Go (nested logic, complex conditionals, class cohesion, renamed clones), and uses PMD when it is installed (copy-paste detection, Java God Class). See DESIGN.md for the model.

Quick start

Requires uv. Run the server from GitHub:

uvx --from git+https://github.com/microbrewerGM/codehealth-mcp codehealth-mcp

Once the package is on PyPI: uvx codehealth-mcp.

Add it to Claude Code for all your projects:

claude mcp add --transport stdio --scope user codehealth -- \
  uvx --from git+https://github.com/microbrewerGM/codehealth-mcp codehealth-mcp

Every other client (Claude Desktop config and MCP Bundle, Codex CLI, Cursor, VS Code, Kiro IDE and CLI) is covered in docs/harnesses.md, with ready-to-copy files in examples/.

To make agents use it, paste examples/AGENTS.md into your repository's agent instructions: review before and after edits, run the pre-commit safeguard before every commit.

Related MCP server: ARGUS

MCP tools

tool

purpose

code_health_score

file -> score, category, analyzers

code_health_review

file -> score and findings (smell, function, lines, value, threshold, severity, hint)

pre_commit_code_health_safeguard

repository -> staged and modified files vs HEAD, quality gate

analyze_change_set

repository + base ref -> per-file verdict on the branch, quality gate

rules_config_validate

check .codehealth/rules.json

rules_config_list_thresholds

thresholds and defaults per language

rules_config_set_rule / rules_config_set_threshold

edit .codehealth/rules.json

explain_code_health

the model, a smell, or the score bands

Results are structured objects (MCP structuredContent), with the same JSON as text for older clients. All paths must be absolute.

Optional: PMD

PMD needs Java 8+. Install the pinned release (SHA-256 checked) once:

uvx --from git+https://github.com/microbrewerGM/codehealth-mcp codehealth install-pmd
# or: codehealth install-pmd --dir /some/dir   (then set CODEHEALTH_PMD_HOME)

The default location is the per-user data directory (~/Library/Application Support/codehealth-mcp/pmd on macOS, $XDG_DATA_HOME/codehealth-mcp/pmd or ~/.local/share/codehealth-mcp/pmd on Linux). Without PMD or Java every tool still works; smells that needed PMD are listed under analyzers.unavailable_smells.

variable

meaning

CODEHEALTH_PMD_HOME

PMD pmd-bin-* directory (or a directory that holds one); also the install-pmd target

CODEHEALTH_NO_PMD=1

do not use PMD

CODEHEALTH_PMD_TIMEOUT

seconds per PMD run (default 120)

CODEHEALTH_CACHE_DIR

PMD cache and scratch copies (default ~/.cache/codehealth)

JAVA_HOME

Java runtime for PMD (else java on PATH)

Configuration

Put rule weights and threshold overrides in .codehealth/rules.json at the repository root (the first rule set whose glob matches a file applies):

{"rule_sets": [{"matching_content_path": "tests/**",
                "rules": [{"name": "Large Method", "weight": 0}],
                "thresholds": [{"name": "function_lines_of_code_warning", "value": 120}]}]}

A comment @codehealth(disable:"Complex Method") or @codehealth(disable-all) right before a function skips function-level smells for that function.

CLI

codehealth review path/to/file.py     # score + findings
codehealth score src/                 # scores for a tree
codehealth delta                      # uncommitted changes vs HEAD (exit 1 when the gate fails)
codehealth delta --base main          # branch vs merge base
codehealth serve                      # MCP server on stdio (same as codehealth-mcp)
codehealth install-pmd [--dir DIR]    # optional PMD install

Development

uv sync
uv run pytest                                   # PMD tests run when PMD + Java are found
CODEHEALTH_NO_PMD=1 uv run pytest               # without PMD (pmd tests skip)
uv run python scripts/dogfood.py                # review this repo through its own MCP server
uv build                                        # sdist + wheel in dist/
scripts/build_mcpb.sh                           # Claude Desktop bundle in dist/

.mcp.json registers the server from this checkout (uv run codehealth-mcp) for Claude Code. The benchmark against human maintainability ratings is in bench/.

Influences and acknowledgements

CodeHealth is an independent implementation. No third-party product code or binaries were used. It is shaped by the following public work:

  • CodeScene public Code Health documentation (https://codescene.io/docs/guides/technical/code-health.html) and its published default rule thresholds, which our default threshold names and values (src/codehealth/thresholds.py, rows marked "published default") follow. The score formula, weights and severity model are our own.

  • Adam Tornhill's writing: https://adamtornhill.substack.com and his books on behavioral code analysis (Your Code as a Crime Scene, Software Design X-Rays), which shaped the agent guidance (delta-first gates, small refactoring loops).

  • Research papers:

    • Adam Tornhill, Markus Borg. "Code Red: The Business Impact of Code Quality -- A Quantitative Study of 39 Proprietary Production Codebases". TechDebt 2022. https://arxiv.org/abs/2203.04374

    • Markus Borg, Ilyana Pruvost, Enys Mones, Adam Tornhill. "Increasing, not Diminishing: Investigating the Returns of Highly Maintainable Code". TechDebt 2024, DOI 10.1145/3644384.3644471. https://arxiv.org/abs/2401.13407

    • Markus Borg, Marwa Ezzouhri, Adam Tornhill. "Ghost Echoes Revealed: Benchmarking Maintainability Metrics and Machine Learning Predictions Against Human Assessments". ICSME 2024 industry track, pp. 678-688, DOI 10.1109/ICSME58944.2024.00072. https://arxiv.org/abs/2408.10754

    • Adam Tornhill, Markus Borg, Nadim Hagatulah, Emma Söderberg. "ACE: Automated Technical Debt Remediation with Validated Large Language Model Refactorings". FSE Companion '25 (AI-IDE workshop), DOI 10.1145/3696630.3730565. https://arxiv.org/abs/2507.03536

  • lizard (MIT, Terry Yin and contributors): per-function metrics.

  • PMD (BSD-style licence): CPD copy-paste detection and Java design rules.

  • tree-sitter (MIT) and tree-sitter-language-pack (MIT OR Apache-2.0): parsing.

  • Datasets used by the benchmark (not redistributed; see bench/README.md):

    • Markus Schnappinger, Arnaud Fietzke, Alexander Pretschner. "A Software Maintainability Dataset", DOI 10.6084/m9.figshare.12801215.v3, CC BY 4.0.

    • Ghost Echoes replication package, Zenodo 12548630 (DOI 10.5281/zenodo.12548630), CC BY 4.0.

Licences of the runtime dependencies: THIRD_PARTY_NOTICES.md.

Licence

MIT, see LICENSE.

Available Tools

9 tools
analyze_change_setA

Compare every changed file on the current branch with its merge base.

When to use: before opening or merging a pull request.
Limitations: compares committed HEAD content only; uncommitted edits are
ignored. The merge base's root rules file is used for both sides.
Returns: {quality_gate, merge_base, counts, rules_changed?, files:[{path, verdict, ...}],
cross_file_duplication?, analyzers?}.

Inputs: repository_path (required), base_ref. Returns: object

code_health_reviewA

Review one source file and list its code smells.

When to use: to decide what to refactor, or to check that an edit did not
add smells. Fix the findings with the highest severity first.
Limitations: static analysis of a single file; duplication within the
file only (needs PMD). analyzers lists which analyzers ran and which
smells were unavailable for this language.
Returns: {score, category, findings:[{smell, level, function,
start_line, end_line (null for whole-file findings), value, threshold,
severity, message, hint, details}],
pmd_violations?, analyzers:{lizard, tree_sitter, pmd, unavailable_smells}}.

Inputs: file_path (required). Returns: object

code_health_scoreA

Score one source file for maintainability.

When to use: a quick health check of a file before or after editing it.
Limitations: one file at a time; some smells need a tree-sitter adapter
(Python, JS, TS/TSX, Java, Go) or PMD, see the analyzers field.
Returns: {path, language, score 1-10, category, optimal, analyzers}.

Inputs: file_path (required). Returns: object

explain_code_healthA

Explain the Code Health model, a smell, or the score bands.

When to use: to understand a finding or how the score is computed.
Limitations: static documentation; pass a smell name or 'score' as topic.
Returns: {topic, text}.

Inputs: topic. Returns: object

pre_commit_code_health_safeguardA

Check staged and modified files against HEAD before committing.

When to use: before every commit made by an agent.
Limitations: tracked files only (untracked files are skipped); compares
the working tree with HEAD using HEAD's root rules file for both sides.
Returns: {quality_gate: passed|failed, counts, rules_changed?,
files:[{path, verdict (improved|degraded|stable|removed|unknown),
old_score, new_score, new_findings, worsened, improved, fixed}],
cross_file_duplication?: CPD copies and renamed clones between changed files (informational),
analyzers?}.

Inputs: repository_path (required). Returns: object

rules_config_list_thresholdsA

List every threshold with its default value and source.

When to use: before overriding a threshold, to see names and defaults.
Limitations: shows defaults, not a repository's overrides.
Languages without their own template fall back to the baseline values
(template: false).
Returns: {language, template, thresholds:[{name, value, operator, published, description}], rules:[names]}.

Inputs: language. Returns: object

rules_config_set_ruleA

Set a rule's weight in the repository rules file (0 disables the rule).

When to use: to silence or soften a smell for part of a repository.
Limitations: writes the rules file in the repository root; the first
matching rule set wins, so a new specific glob is placed first.
Returns: {rules_file, rule, weight, matching_content_path}.

Inputs: weight (required), rule_name (required), repository_path (required), matching_content_path. Returns: object

rules_config_set_thresholdB

Override a threshold in the repository rules file.

When to use: when a team agrees on a different limit, e.g. longer functions in tests.
Limitations: names must come from rules_config_list_thresholds.
Returns: {rules_file, threshold, value, matching_content_path}.

Inputs: value (required), threshold_name (required), repository_path (required), matching_content_path. Returns: object

rules_config_validateA

Validate the repository's code health rules file.

When to use: after editing .codehealth/rules.json.
Limitations: checks structure, rule names and threshold names only.
Returns: {rules_file, valid, errors}.

Inputs: repository_path (required). Returns: object

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A3.7/5.0

    Scored across 9 tools

    Disambiguation4/5

    Most tools are clearly distinct (explain vs. analyze vs. rules configuration), and the two closest pairs — code_health_score vs. code_health_review and pre_commit_code_health_safeguard vs. analyze_change_set — are separated by explicit 'when to use' framing (quick score vs. full findings; staged/HEAD vs. merge base). The score/review pair still shares nearly identical inputs and only differs in output depth, so an agent could pick the lighter tool when it needed findings.

    Naming Consistency3/5

    Conventions are mixed: code_health_score and code_health_review use a noun-prefix form, explain_code_health flips to verb-first, analyze_change_set is verb_noun, pre_commit_code_health_safeguard has no verb at all, and the rules_config_* family uses a different noun_noun_verb ordering. Each name is individually readable, but there is no single predictable pattern to infer a tool from.

    Tool Count5/5

    Nine tools is well within the ideal range and each one earns its place: two analysis entry points, two change-comparison entry points, documentation, and four rules-file operations. Nothing appears redundant or bolted on.

    Completeness4/5

    The surface covers the lifecycle well — score, detailed review, explanation, pre-commit gate, branch-level change analysis, and full rules read/validate/write. Gaps remain around reading back the effective repository rules (only defaults are listed) and any multi-file or directory-level scan, since analysis is one file at a time.

    Maintenance

    ActivityMaintained
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      A
      quality
      B
      maintenance
      Enables AI assistants and developers to analyze code for language-specific best practices and idiomatic patterns across programming languages, CI automation, and configuration formats.
      16
      2
      MIT
    • F
      license
      B
      quality
      C
      maintenance
      Enables AI agents to perform comprehensive, zero-infrastructure codebase analysis through 24 MCP tools, covering security, quality, architecture, type safety, git history, and dead code detection with high precision and local privacy.
      45
      -
    • A
      license
      Not graded
      quality
      C
      maintenance
      Enables AI coding agents to analyze repository architecture, changed-file and diff impact, dependency and endpoint exposure, API contract compatibility, architecture boundaries, bounded capacity simulations, and security/quality evidence through MCP tools.
      3
      Apache 2.0