PHPackages                             dpt/mcp-phpmd-warm - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Testing &amp; Quality](/categories/testing)
4. /
5. dpt/mcp-phpmd-warm

ActiveProject[Testing &amp; Quality](/categories/testing)

dpt/mcp-phpmd-warm
==================

Warm-process MCP server for PHPMD. Keeps PHPMD's classes + parsed rulesets bootstrapped across calls — faster per-file mess detection vs cold CLI invocation. Compatible with any MCP client (Claude Desktop, Cline, Continue, Zed, custom).

v0.1.0(1mo ago)13.1k↓23.6%proprietaryPHPPHP &gt;=8.2CI passing

Since May 29Pushed 1mo ago1 watchersCompare

[ Source](https://github.com/Digital-Process-Tools/mcp-phpmd-warm)[ Packagist](https://packagist.org/packages/dpt/mcp-phpmd-warm)[ Docs](https://github.com/Digital-Process-Tools/mcp-phpmd-warm)[ RSS](/packages/dpt-mcp-phpmd-warm/feed)WikiDiscussions main Synced 1w ago

READMEChangelogDependencies (4)Versions (3)Used By (0)

 [![mcp-phpmd-warm — mess caught warm. smells surface at edit, not push.](banner.png)](banner.png)

mcp-phpmd-warm
==============

[](#mcp-phpmd-warm)

> **Stop paying [PHPMD](https://phpmd.org/)'s cold-start tax on every edit.**A warm-process [MCP](https://modelcontextprotocol.io/) server that keeps PHPMD's classes + parsed rulesets hot. ~24× faster per call. Works with every MCP client.

[![Tests](https://github.com/Digital-Process-Tools/mcp-phpmd-warm/actions/workflows/tests.yml/badge.svg)](https://github.com/Digital-Process-Tools/mcp-phpmd-warm/actions/workflows/tests.yml)[![Packagist](https://camo.githubusercontent.com/d8a121433efc8ab976f36db1454c412ee9c715f981f5b8fe0a2b314efca498c9/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f6470742f6d63702d7068706d642d7761726d2e737667)](https://packagist.org/packages/dpt/mcp-phpmd-warm)[![PHP](https://camo.githubusercontent.com/344e820b219cee3234648531306104364bd684892ad13c5dc79e66eb82a15b90/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f7068702d382e322532422d626c7565)](https://www.php.net/)[![License](https://camo.githubusercontent.com/b070db700d7549b4414d6c41907c169824e89a1e3e949816af5828685facd257/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d436f6d6d756e6974792d627269676874677265656e)](LICENSE)

[Why](#why) • [Install](#install) • [Use it](#use-it) • [Benchmark](#benchmark) • [Compatibility](#compatibility) • [How it works](#how-it-works) • [FAQ](#faq)

---

Why
---

[](#why)

[PHPMD](https://phpmd.org/) catches the smells that break a build at the finish line — excessive complexity, god classes, unused code, naming violations. The catch: those smells usually surface only at **pre-push**, long after the edit that caused them. By then it's a fix-amend-repush cycle instead of a one-line decision made while the code is still warm in your head.

Wiring PHPMD into the edit loop fixes that — except every `phpmd foo.php` pays the same toll: interpreter boot, autoloader, ruleset XML parse, PHPDepend warm-up. Cheap once, expensive 100 times.

`mcp-phpmd-warm` runs PHPMD inside a long-lived PHP process. **First call pays the boot once. Every subsequent call reuses the hot interpreter, opcache and autoloader.**

Install
-------

[](#install)

```
composer global require dpt/mcp-phpmd-warm
```

Makes `mcp-phpmd-warm` available on `$PATH`.

Requires PHP 8.2+. Pulls PHPMD ^2.15 as a real Composer dep.

Use it
------

[](#use-it)

### Claude Desktop

[](#claude-desktop)

Edit `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) or `%APPDATA%\Claude\claude_desktop_config.json` (Windows):

```
{
  "mcpServers": {
    "phpmd": {
      "command": "mcp-phpmd-warm",
      "args": [
        "--working-dir=/path/to/your/project",
        "--rulesets=cleancode,codesize,design,naming,unusedcode"
      ]
    }
  }
}
```

Restart Claude. Ask: *"Run PHPMD on src/Foo.php"*.

`--rulesets` accepts PHPMD's built-in ruleset names **or** absolute paths to custom ruleset XML files (or any mix). Omit it to use PHPMD's defaults.

### Cline / Continue / Cursor / Zed / any MCP client

[](#cline--continue--cursor--zed--any-mcp-client)

Same `command` + `args` shape. The server speaks plain MCP over stdio — no client-specific glue.

### Standalone

[](#standalone)

```
mcp-phpmd-warm --working-dir=/path/to/project --rulesets=cleancode,design,naming
```

Reads MCP JSON-RPC on stdin, writes responses on stdout.

Benchmark
---------

[](#benchmark)

Measured on a small PHP file with 5 rulesets (`cleancode,codesize,design,naming,unusedcode`):

SetupPer-call wallNotesCold phpmd CLI~315msinterpreter + autoload + ruleset parse each time**mcp-phpmd-warm (warm)****~13ms**classes + opcache hot, rulesets rebuilt per callDaemon cold boot~90mspaid **once** at server start**~24× faster per call.** Numbers vary with project size and ruleset count. The win is cold-start amortization, not magic — and PHPMD is a lighter tool than Rector or PHPStan, so its absolute cold cost is smaller to begin with.

Compatibility
-------------

[](#compatibility)

ClientStatusClaude Desktop✅ stdio MCPCline (VS Code)✅ stdio MCPContinue (VS Code / JetBrains)✅ stdio MCPCursor✅ stdio MCPZed✅ stdio MCPCustom (Python/Node/Go MCP clients)✅ standard protocolAny client that speaks MCP stdio works. No custom protocol.

Tools exposed
-------------

[](#tools-exposed)

### `phpmd_analyse`

[](#phpmd_analyse)

Run PHPMD mess detection on a path. Rulesets are server-pinned (`--rulesets`).

ArgumentTypeDefaultDescription`path`stringrequiredAbsolute path to a file under the working dirReturns:

```
{
  "exit_code": 0,
  "output": "{...PHPMD JSON report...}",
  "warm_boot": true
}
```

`exit_code`: `0` clean, `2` violations found, `-1` error. `warm_boot: true` ⇒ hot process reused. `false` ⇒ first call (cold boot just finished). `output` is PHPMD's JSON renderer payload.

How it works
------------

[](#how-it-works)

Three decisions worth knowing:

1. **One daemon per project, not per call.** Working dir + rulesets pin at server startup (`--working-dir`, `--rulesets`). The process stays alive, so the expensive part — loading hundreds of PHPMD + PHPDepend classes — happens once.
2. **No container to cache — PHPMD has none.** Unlike Rector, the win here is purely the persistent interpreter: opcache and the autoloader stay hot. There's nothing stateful to keep warm beyond that.
3. **Rulesets are rebuilt per call, on purpose.** Some PHPDepend rules accumulate per-run state, so reusing `RuleSet` objects across files would leak violations from one file into the next. Ruleset XML parsing is cheap relative to the boot cost already amortized, so each call gets a fresh `RuleSetFactory` + `Report` + renderer. Verified leak-free by test.

FAQ
---

[](#faq)

**Does this replace `vendor/bin/phpmd`?** No. Use it from MCP clients (Claude Desktop, agents). For one-off CLI calls the regular binary is still simpler.

**Can I use my project's custom ruleset XMLs?** Yes — pass their absolute paths in `--rulesets`, comma-separated, mixed freely with built-in ruleset names.

**Why rebuild rulesets every call if it's a *warm* server?** Correctness beats a few ms. The dominant cold cost is class loading, not ruleset parsing, and that's what the persistent process eliminates.

**Memory?** The daemon sets `memory_limit = -1` like PHPMD's own CLI. Idle daemon is small — PHPMD is a lighter dependency tree than Rector.

**Does it survive PHPMD version updates?** It uses PHPMD's stable public API (`PHPMD::processFiles`, `RuleSetFactory`, `JSONRenderer`). Pin a PHPMD version in your own `composer.json` if you need determinism.

Credits
-------

[](#credits)

- **[PHPMD](https://github.com/phpmd/phpmd)** by Manuel Pichler and contributors — the mess detector doing the real work.
- **[PHPDepend](https://github.com/pdepend/pdepend)** — the parser PHPMD is built on.
- **[Model Context Protocol](https://modelcontextprotocol.io/)** by Anthropic — the protocol that makes this kind of tool integration possible.
- **[mcp/sdk](https://github.com/modelcontextprotocol/php-sdk)** — official PHP SDK, used here for stdio transport + tool discovery.

Related
-------

[](#related)

- **[PHPMD docs](https://phpmd.org/documentation/index.html)** — rules, rulesets, custom XML.
- **[PHPMD on Packagist](https://packagist.org/packages/phpmd/phpmd)** — the upstream package.
- **[mcp-rector-warm](https://github.com/Digital-Process-Tools/mcp-rector-warm)** • **[mcp-phpstan-warm](https://github.com/Digital-Process-Tools/mcp-phpstan-warm)** • **[mcp-phpunit-warm](https://github.com/Digital-Process-Tools/mcp-phpunit-warm)** — the sibling warm-process servers.
- **[claude-supertool](https://github.com/Digital-Process-Tools/claude-supertool)** — DPT's batched-ops Claude Code companion; integrates this server as a validator.

License
-------

[](#license)

Community License — see [LICENSE](LICENSE). Built by [Digital Process Tools](https://github.com/Digital-Process-Tools).

###  Health Score

42

—

FairBetter than 88% of packages

Maintenance89

Actively maintained with recent releases

Popularity25

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity37

Early-stage or recently created project

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

56d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/150798857?v=4)[Florian DAVID](/maintainers/fdaviddpt)[@fdaviddpt](https://github.com/fdaviddpt)

---

Top Contributors

[![fdaviddpt](https://avatars.githubusercontent.com/u/150798857?v=4)](https://github.com/fdaviddpt "fdaviddpt (1 commits)")

---

Tags

phpstatic analysisphpmdmess detectormcpclaudeModel Context Protocolai-tools

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/dpt-mcp-phpmd-warm/health.svg)

```
[![Health](https://phpackages.com/badges/dpt-mcp-phpmd-warm/health.svg)](https://phpackages.com/packages/dpt-mcp-phpmd-warm)
```

###  Alternatives

[symfony/ai-mate

AI development assistant MCP server for Symfony projects

28170.6k34](/packages/symfony-ai-mate)[vizra/vizra-adk

Vizra Agent Development Kit - A comprehensive Laravel package for building intelligent AI agents.

29434.2k](/packages/vizra-vizra-adk)[testo/testo

A lightweight PHP testing framework.

1959.3k116](/packages/testo-testo)[php-code-archeology/php-code-archeology

Static analyzer for PHP project archeology. Calculates various metrics for your codebase.

835.2k](/packages/php-code-archeology-php-code-archeology)[stimmt/craft-mcp

MCP (Model Context Protocol) server for Craft CMS

261.9k](/packages/stimmt-craft-mcp)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
