mcp-magento-audit
This MCP server lets an AI agent audit Magento 2 / Adobe Commerce projects for upgrade readiness, custom module risk, and dependency security.
Get a fast composer-only project overview: Magento version, PHP requirement, package count, and abandoned packages.
Check package compatibility against a target PHP/Magento version, plus Rector-based code compatibility.
Scan custom module risk: phpcs, phpstan, rector, third-party vendor Magento modules, ObjectManager misuse, core overrides, and dangling XML references.
Audit installed packages for known security advisories via
composer audit.List outdated packages with newer available versions via
composer outdated.Fetch Magento's official release notes from GitHub without relying on model memory.
Build a concrete upgrade plan with blockers, unverified signals, and
readystatus.Triage many projects at once for fleet-wide upgrade readiness.
Fetches release notes for magento/magento2 from GitHub Releases to support upgrade planning without relying on model memory.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@mcp-magento-auditassess this Magento project for PHP 8.3 / Magento 2.4.8 upgrade blockers"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
mcp-magento-audit

An MCP server giving an AI agent tools to assess a Magento 2 / Adobe Commerce project along three axes: compatibility with a target PHP and Magento version, quality of custom modules, and dependency security.
It answers the question that never stops coming up in Magento agencies: "can we bump this client to a newer version, what's blocking it, and where do we start?"
Status: early stage. Built on evenings/weekends. All eight planned tools (
get_project_status,check_updates,scan_module_risk,audit_security,check_outdated_packages,fetch_release_notes,build_upgrade_plan,build_fleet_overview) are working. SeeROADMAP.mdfor what's next.
How this differs from composer audit
composer audit and composer outdated are built into Composer and do their job well —
audit_security and check_outdated_packages actually shell out to them rather than
reimplementing a CVE database or version comparison. This server targets what plain
Composer doesn't give you:
It doesn't see
app/code. Custom modules don't exist on Packagist, so they get zero coverage from vulnerability databases — and that's exactly the code agencies write.scan_module_riskcovers that side withphpcs/phpstan/rectorinstead.It doesn't combine axes. Nobody gets one answer: this module blocks the upgrade, has an open CVE, is abandoned by its author, and has the worst complexity in the project — fix this one first.
build_upgrade_plandoes, foldingaudit_security's advisories in alongside composer-constraint and code-quality blockers.It doesn't aggregate across projects. "Which of our twenty stores can be upgraded today" requires stitching results together from many directories by hand.
build_fleet_overviewruns the composer-constraint check across every project path given to it in one call — a fast first pass, not a replacement for a fullbuild_upgrade_planper project.
What this server doesn't pretend to be: there's no clean dataset of "module X works
with Magento 2.4.8". Results are derived from declarations in composer.json, a code
scan, and the vendor's own release notes — this is a decision-support tool, not an
oracle. Upgrading a production store still requires testing, not just a report.
Related MCP server: Magento MCP Server
Install
git clone https://github.com/michalper/mcp-magento-audit.git
cd mcp-magento-audit
python3.12 -m venv .venv
.venv/bin/pip install -e ".[dev]"Connecting to Claude Code
{
"mcpServers": {
"magento-audit": {
"command": "/path/to/mcp-magento-audit/.venv/bin/mcp-magento-audit"
}
}
}Projects that develop inside Docker/DDEV/Warden/Lando
scan_module_risk (phpcs/phpstan/rector), check_updates's code_compatibility signal, and
audit_security/check_outdated_packages all shell out to the project's own vendor/bin/*
and composer. If that project only has PHP/Composer available inside a dev container
— common for Magento — and this MCP server runs on the host, every one of those checks
will correctly report scanned=false with a reason rather than silently being wrong, but
that's easy to misread as "found nothing" instead of "couldn't check".
Set MCP_MAGENTO_AUDIT_EXEC_PREFIX to wrap every one of those calls in a command that
runs it inside the container instead, e.g.:
export MCP_MAGENTO_AUDIT_EXEC_PREFIX="ddev exec --"
# or: export MCP_MAGENTO_AUDIT_EXEC_PREFIX="docker compose exec -T app"This assumes the usual bind-mount setup (the project directory mirrors the same
relative layout inside the container, just under a different root) — host-absolute
paths like vendor/bin/phpcs are rewritten relative to the project root before being
wrapped, and composer resolves against the container's own PATH rather than the
host's. If that assumption doesn't hold for a given setup, running this server from
inside the dev container directly (no prefix needed) is the more reliable fallback.
Rate limits on GitHub API calls
fetch_release_notes calls the GitHub REST API, capped at 60 requests/hour per IP when
unauthenticated — easily hit from a shared office/CI IP running build_fleet_overview or
build_upgrade_plan across many projects. Set GITHUB_TOKEN (or GH_TOKEN) in the
environment to raise that to 5000/hour; a read-only, no-scope token is enough, since this
only ever reads public release data.
Example

An agent calling build_upgrade_plan against a store that has one abandoned, PHP-7-only
package and no phpstan.neon of its own (trimmed — the real result also includes
release_notes, and the full update_check/scan_module_risk results each blocker was
derived from):
{
"ready": false,
"unverified": [
"phpstan: no phpstan.neon(.dist) in project — skipping static analysis"
],
"blockers": [
{
"source": "composer",
"description": "legacy/module",
"detail": "^7.4 does not cover PHP 8.3"
}
]
}ready is false because of a real blocker, not a guess; unverified says phpstan never
ran at all, so a clean result elsewhere isn't mistaken for "everything was checked".
Tools
Tool | Status | Description |
| working | Magento version, PHP requirement, package count, abandoned packages |
| working | per-package verdict against a target PHP/Magento version, plus a Rector-based check of whether the code itself would need changes |
| working | scans code via |
| working | every installed package in |
| working | every installed package checked against |
| working | release notes from |
| working | combines the other tools into a list of concrete blockers, with |
| working | triages many projects at once against a target PHP/Magento version ("which of these N stores can be upgraded today") via |
Development
.venv/bin/python -m pytest --cov # tests + coverage
.venv/bin/ruff check . # lint
.venv/bin/mypy src # types
.venv/bin/bandit -c pyproject.toml -r src # security
.venv/bin/pip-audit # dependency vulnerabilitiesRun .venv/bin/pre-commit install once to run all of the above (except
pip-audit, which needs network access and stays CI-only) on every commit.
Architectural decisions are recorded in docs/adr/. See CHANGELOG.md for what
changed in each release.
License
MIT
Available Tools
8 toolsaudit_securityA
Checks every installed package in the given Magento project's composer.lock — core Magento, third-party vendor/ extensions, dev dependencies, not just custom app/code — against known security advisories via composer audit. Returns scanned=false with a reason (e.g. no composer.lock, composer not found) rather than silently reporting zero advisories when the check never ran.
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | Filesystem path to the Magento project root (holds composer.json). |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full disclosure burden and does it well: it names the underlying mechanism (`composer audit`), the failure modes (no composer.lock, composer not found), and, critically, that it returns scanned=false with a reason rather than reporting a false zero. That failure-semantics detail is exactly the kind of behavior an agent cannot infer from the schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, both load-bearing: the first establishes scope, the second establishes failure semantics. It is slightly dense with an em-dash appositive list, but nothing is redundant and the scope statement leads.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return-value explanation is not required, yet the description still adds the one return contract that matters (scanned=false on a skipped check). With one simple required parameter and the mechanism, scope, and failure behavior all stated, nothing an agent needs to invoke this correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% on a single parameter, so the schema already documents that `path` is the project root holding composer.json. The description only restates the same relationship ('the given Magento project') without adding format or edge-case detail beyond the schema. Baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Specific verb (checks against known security advisories) and precise resource scope (every installed package in composer.lock: core, vendor, dev dependencies). The explicit contrast 'not just custom app/code' distinguishes it from narrower siblings like scan_module_risk without naming them.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The stated scope makes the intended context clear — you run this to audit dependency advisories rather than custom code — which implicitly separates it from scan_module_risk and check_outdated_packages. However, no alternative tool is named and there is no explicit when-not guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
build_fleet_overviewA
Triages many Magento projects at once against a target PHP/Magento version — 'which of these N stores can be upgraded today'. Runs only check_updates per project (composer-constraint verdicts, plus code_compatibility if the project has its own rector.php) — deliberately not the full build_upgrade_plan, since scan_module_risk's phpcs/phpstan/rector and audit_security's/check_outdated_packages' composer calls are each seconds-to-minutes and don't scale across a whole fleet in one call. A project reported blocked=false here can still have scan_module_risk/audit_security findings that build_upgrade_plan would catch — call build_upgrade_plan per project afterward for the full picture. A project that fails to load (bad path, missing composer files) is reported with its own error instead of failing the whole batch.
| Name | Required | Description | Default |
|---|---|---|---|
| paths | Yes | Filesystem paths to the Magento project roots to triage, one per project. | |
| target_php | Yes | Target PHP version to check compatibility against, e.g. "8.3". | |
| target_magento | Yes | Target Magento version to check compatibility against, e.g. "2.4.7". |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does well: it discloses exact scope (only check_updates per project, plus code_compatibility when rector.php exists), the reasoning for omitting expensive checks, and batch failure semantics (a bad path errors individually instead of failing the whole call). It stops short of stating whether the operation is read-only or how long a fleet-wide run may take, so it is strong but not exhaustive.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the purpose and dense with distinct facts (scope, cost rationale, caveat, error handling); no filler sentences. It is on the long side with nested clauses, but each sentence delivers a separate, actionable point.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given an output schema exists (so return values need not be described) and the batch/nested-parameter complexity is low, the description covers everything an agent needs: what it runs, what it deliberately omits, the important false-negative caveat about blocked=false, and per-project error containment.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% for all three required params, so the baseline is 3. The description reinforces the aggregate semantics of 'paths' (one per project) and the target versions, but adds no syntax, format, or edge-case detail beyond what the schema already documents.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Names a specific verb (triages) and resource (many Magento projects/fleet) and even frames the question it answers: 'which of these N stores can be upgraded today'. It explicitly contrasts itself with build_upgrade_plan and the heavier scan_module_risk/audit_security siblings, so an agent can distinguish it without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit when-to-use ('triages many projects at once', 'today' triage) and when-not-to-expect-completeness, plus a prescribed follow-up ('call build_upgrade_plan per project afterward for the full picture'). The alternative path is named rather than left for inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
build_upgrade_planA
Builds an upgrade plan for the given Magento project against a target PHP and Magento version by combining check_updates, scan_module_risk, audit_security, check_outdated_packages and fetch_release_notes. The verdict is a list of concrete blockers (composer constraints, code that Rector flags as needing changes, phpcs/phpstan errors in the project's own app/code, security advisories against installed packages), each with its own reason — not a single abstract score. check_outdated_packages and vendor/-scope scan_module_risk issues are informational only (included in the full result, not in blockers): being behind on releases, or a third-party module's own code quality, don't block this upgrade the way an app/code error or a composer constraint does. ready=true only when the blockers list is empty, but check 'unverified' too: it lists any signal that couldn't run at all (e.g. phpstan/rector not installed, or composer missing for audit_security/check_outdated_packages), which ready=true does not account for.
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | Filesystem path to the Magento project root (holds composer.json). | |
| target_php | Yes | Target PHP version to check compatibility against, e.g. "8.3". | |
| target_magento | Yes | Target Magento version to check compatibility against, e.g. "2.4.7". |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral burden and does substantial work: it defines what qualifies as a blocker, declares check_outdated_packages and vendor/-scope scan_module_risk findings as informational-only, and warns that ready=true ignores the 'unverified' list. It does not state whether the tool mutates anything or any runtime/performance expectations for running five sub-checks, leaving modest gaps.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Purpose and the composed tool list are front-loaded, and the sentences are dense with decision-relevant content rather than filler. It is on the long side and re-explains return-value semantics the output schema likely already covers, which costs a point.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a multi-tool orchestrator this covers the essential surface: inputs, what is combined, blocker vs informational semantics, and the ready/unverified caveat. Since an output schema exists, the description needn't detail return shape, and the remaining omission (side-effect/performance profile against a local filesystem path) is minor.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% for all three required parameters, so the schema already documents path, target_php and target_magento with format examples. The description adds no parameter-level detail beyond what the schema provides, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ("Builds an upgrade plan") and immediately scopes it to a Magento project against target PHP/Magento versions. It also names the exact siblings it composes (check_updates, scan_module_risk, audit_security, check_outdated_packages, fetch_release_notes), which cleanly distinguishes this aggregator from the individual check tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The composition list makes clear that this is the orchestration entry point rather than a call to each sibling individually, and it explains how to interpret output signals that select routes (blockers vs informational). It does not, however, explicitly state when NOT to use it (e.g. when you only need one check), so guidance is strong but not exhaustive.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
check_outdated_packagesA
Checks every installed package in the given Magento project's composer.lock against composer outdated to report which ones have a newer version available — independent of audit_security (known CVEs) and check_updates (compatibility with a target PHP/Magento version): a package can be behind on releases with neither of those issues, and that's still tech debt worth surfacing. Each package's own latest-status (e.g. semver-safe-update vs update-possible) is included as reported by Composer. Returns scanned=false with a reason (e.g. no composer.lock, composer not found) rather than silently reporting zero outdated packages.
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | Filesystem path to the Magento project root (holds composer.json). |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral burden and does well: it discloses the data source (composer.lock vs `composer outdated`), the per-package latest-status values (semver-safe-update vs update-possible), and a failure mode where scanned=false plus a reason is returned instead of a misleading zero. It stops short of stating permissions, runtime cost, or whether the scan hits the network.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The core action is front-loaded in the first clause, and the differentiation and failure-mode notes are dense rather than padded. The single long em-dash-heavy sentence runs on, but no sentence is wasted.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return-value documentation is not required, yet the description still explains the per-package status field and the scanned=false degradation path. For a one-parameter scan tool this covers everything an agent needs to call it and interpret the result.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and the single `path` parameter is fully documented in the schema as the project root holding composer.json. The description adds only the related detail that composer.lock lives there, which does not extend meaning beyond the schema. Baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Checks every installed package ... against `composer outdated`') and anchors it to a concrete artifact (composer.lock in the Magento project root). It explicitly separates itself from two named siblings, audit_security and check_updates, so an agent can pick it without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Names both alternatives and the precise condition that selects this tool: a package can be behind on releases with neither a CVE nor a compatibility issue, 'and that's still tech debt worth surfacing.' That is an explicit when-to-use rationale plus implicit when-not (use audit_security/check_updates for those concerns).
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
check_updatesA
Checks the given Magento project against a target PHP and Magento version, with two independent signals: a per-package verdict ('ok', 'blocks' or 'unknown') from declared composer.lock PHP requirements, and code_compatibility — whether the project's own code would actually need changes under the target PHP, via a Rector dry-run (declared requirements are often just '*', which alone gives a false sense of readiness). The PHP requirement for the target Magento version comes from a local cache, a live fetch, or an offline fallback table, in that order — the result says which one was used.
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | Filesystem path to the Magento project root (holds composer.json). | |
| target_php | Yes | Target PHP version to check compatibility against, e.g. "8.3". | |
| target_magento | Yes | Target Magento version to check compatibility against, e.g. "2.4.7". |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full disclosure burden and does substantial work: it explains that declared requirements are often '*' and can give a false sense of readiness, that code_compatibility requires a Rector dry-run, and that the PHP source is resolved from cache, live fetch, or offline fallback table in that order with the result disclosing which. Auth, rate limits, and likely runtime cost of the dry-run are still unstated.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Purpose is front-loaded in the first clause, and the two signals plus the fallback chain follow in a logical order. It is dense and sentence-heavy, with the parenthetical about '*' being essentially a second clause inside an already long sentence, but almost every statement carries real information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need not be described, and the description still explains the shape of the two results and the provenance of the PHP requirement. For a moderately complex, multi-signal check with no annotations, the remaining gap is operational (expected runtime, whether it mutates the working tree via the dry-run) rather than conceptual.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so all three parameters (path, target_php, target_magento) are already documented with examples ('8.3', '2.4.7') in the schema. The description reinforces what the inputs mean but adds no format or constraint detail beyond what the schema already provides, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: it checks a Magento project's readiness against a target PHP and Magento version, and it enumerates the two signals produced (per-package verdict and code_compatibility). That is far more precise than the bare name, but it never positions itself against close siblings like outdated_packages or upgrade_plan, so an agent must infer the distinction.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is only implied: an agent can infer this is an upgrade-readiness check to run before/alongside upgrade_plan, but the description names no alternative, no when-not-to-use condition, and no prerequisites beyond needing a project root with composer.json. It contextualizes the result rather than the invocation decision.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
fetch_release_notesA
Fetches Magento's own release notes for a given version from the magento/magento2 GitHub repo's Releases API — never reconstructs them from training data. Returns found=false with a reason when nothing could be fetched, rather than guessing what a release might have contained.
| Name | Required | Description | Default |
|---|---|---|---|
| version | Yes | Magento version to fetch release notes for, e.g. "2.4.7". |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does disclose meaningful behavior: the authoritative data source, an explicit anti-hallucination guarantee ('never reconstructs them from training data'), and the failure contract ('returns found=false with a reason ... rather than guessing'). It does not cover auth requirements, rate limits, or network/error conditions beyond the not-found case, so it falls short of a 5.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, front-loaded with the action and source, followed by the failure-mode contract. No filler or redundant restatement of the tool name; every clause adds information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return-value shape needn't be explained, and the description still covers the source of truth and the found=false outcome. What remains thin is operational context (auth, rate limits, offline behavior), which matters for a GitHub-API-backed tool but is unmentioned.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and there is a single parameter whose schema already documents the expected format ('2.4.7'). The description adds no format, normalization, or range guidance beyond what the schema provides, so baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource ('Fetches Magento's own release notes') and names the exact source (magento/magento2 GitHub repo's Releases API), so the agent knows precisely what it gets and from where. It is clearly distinguishable from sibling tools like security_audit, check_updates, and upgrade_plan, which operate on installed projects rather than fetching upstream notes.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage (you supply a version and get that version's upstream notes), and the 'never reconstructs from training data' phrasing hints it should be preferred over inferring notes. However, it never explicitly says when to choose this over check_updates or upgrade_plan, nor are any prerequisites stated. Usage is implied rather than instructed.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_project_statusA
Reads composer.json and composer.lock of the given Magento project and returns its state: Magento version, PHP requirement, package count and the list of packages abandoned by their authors. Call this first for a fast, composer-only overview before the deeper (and slower) checks like check_updates, scan_module_risk or build_upgrade_plan.
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | Filesystem path to the Magento project root (holds composer.json). |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the burden; it discloses that the operation only reads composer.json/composer.lock and adds a useful performance trait (fast, composer-only vs slower deeper checks). It does not explicitly state there are no side effects or what happens on a missing/invalid path, so it stops short of full disclosure.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, zero waste, and the output summary is front-loaded before the routing advice. Every clause earns its place by either describing the return or directing sequencing.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so the description needn't explain return values, and it already covers the read source and its place in the tool sequence. The only residual gap is unspecified error behavior for a bad path, which is minor for a single-parameter read tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
There is one parameter with 100% schema description coverage, so the schema already defines 'path' as the project root holding composer.json. The description's phrase 'given Magento project' adds no syntax or format detail beyond the schema, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Reads composer.json and composer.lock of the given Magento project') and enumerates the returned state: Magento version, PHP requirement, package count, abandoned packages. This clearly separates it from siblings like check_updates or scan_module_risk.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly says 'Call this first' for a fast overview before 'the deeper (and slower) checks like check_updates, scan_module_risk or build_upgrade_plan'. Names both the trigger condition and the alternative tools, leaving nothing to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
scan_module_riskA
Scans the given Magento project's custom code for coding-standard violations, static-analysis issues and dead-code/quality suggestions by shelling out to the project's own vendor/bin/phpcs, vendor/bin/phpstan and vendor/bin/rector. phpcs: if the project has its own phpcs.xml(.dist), that configuration is used as-is; otherwise falls back to the Magento2 standard on app/code. phpstan and rector: only run if the project has its own phpstan.neon(.dist)/rector.php — unlike phpcs there is no safe generic fallback (no paths/level/extensions/rule sets to guess), so they're skipped rather than guessing. rector's findings are reported as severity=warning (suggestions, not pass/fail violations). A fourth, separate check (vendor_phpcs) scans third-party vendor/ Magento modules (type magento2-module in composer.lock, excluding magento/* core) with the bare Magento2 standard — the scanned package list is in vendor_packages, and those issues carry scope='vendor' (vs 'app_code' for the rest) so callers can tell code they can fix from code they can't. A fifth check (object_manager_misuse) is a plain regex scan over app/code's own .php/.phtml files for ObjectManager::getInstance() — not a phpcs sniff: magento-coding-standard's only built-in check for this fires solely inside .phtml templates, not in Model/Block/Helper classes where bypassing constructor DI is arguably more harmful. A sixth check (core_overrides) flags app/code classes that redeclare a class already present in vendor/magento/* under the exact same fully qualified name (a copy-pasted core file, not a legitimate di.xml preference/plugin) — severity=error, so unlike the previous two it does become a build_upgrade_plan blocker, since that silently blocks safely updating the vendor copy it shadows. A seventh check (dangling_references) flags app/code's own di.xml (preference/plugin), events.xml (observer), crontab.xml (job), layout XML (block/uiComponent), indexer.xml and schema.graphqls (@resolver) naming a PHP class that doesn't resolve to any known class or virtualType — a stale reference left behind by a rename or removal, invisible to phpcs/phpstan/rector since none of them analyze XML. severity=warning, not a build_upgrade_plan blocker. Each tool reports scanned=false with a reason when it can't run, instead of staying silent.
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | Filesystem path to the Magento project root (holds composer.json). |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does so richly: it discloses the shelling-out mechanism, the phpcs.xml fallback to Magento2 on app/code, the deliberate skipping of phpstan/rector when no config exists (and why no safe fallback), severity assignments per check, scope='vendor' vs 'app_code' tagging, and the scanned=false-with-reason contract.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The single dense paragraph is front-loaded with the overall purpose before enumerating the seven checks, and virtually every sentence carries distinct behavioral information with no filler. It is very long, but for a tool with seven heterogeneous checks the length is largely earned rather than padding.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the complexity, an output schema exists so return shape needn't be explained, yet the description still covers scanned=false handling, severity semantics, and scope tagging. Nothing an agent needs to invoke and interpret this tool correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
A single parameter with 100% schema description coverage: the schema already documents 'path' as the project root holding composer.json. The description adds no syntax or format detail beyond that, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a precise verb+resource: scans a Magento project's custom code for phpcs/phpstan/rector violations plus four additional non-obvious checks (vendor_phpcs, object_manager_misuse, core_overrides, dangling_references). It enumerates each check and its scope, so an agent can distinguish this from sibling tools like audit_security or build_upgrade_plan.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied through the severity/blocker semantics (core_overrides errors feed build_upgrade_plan; warnings do not) and the vendor vs app_code scope split, which tells the caller which findings are actionable. However, it never explicitly states when to run this versus audit_security or the other sibling tools, nor any prerequisites beyond a project path.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
12 tool updates
v0.4.0- Added
audit_security - Added
build_fleet_overview - Added
build_upgrade_plan - Added
check_outdated_packages - Removed
fleet_overview - Added
get_project_status - Removed
module_risk - Removed
outdated_packages - Removed
project_status - Added
scan_module_risk - Removed
security_audit - Removed
upgrade_plan
8 tool updates
- Changed
check_updates3 fields changed- added
Input schema / properties / path / descriptionAdded value: +"Filesystem path to the Magento project root (holds composer.json)." - added
Input schema / properties / target_magento / descriptionAdded value: +"Target Magento version to check compatibility against, e.g. \"2.4.7\"." - added
Input schema / properties / target_php / descriptionAdded value: +"Target PHP version to check compatibility against, e.g. \"8.3\"."
- Changed
fetch_release_notes1 field changed- added
Input schema / properties / version / descriptionAdded value: +"Magento version to fetch release notes for, e.g. \"2.4.7\"."
- Changed
fleet_overview3 fields changed- added
Input schema / properties / paths / descriptionAdded value: +"Filesystem paths to the Magento project roots to triage, one per project." - added
Input schema / properties / target_magento / descriptionAdded value: +"Target Magento version to check compatibility against, e.g. \"2.4.7\"." - added
Input schema / properties / target_php / descriptionAdded value: +"Target PHP version to check compatibility against, e.g. \"8.3\"."
- Changed
module_risk1 field changed- added
Input schema / properties / path / descriptionAdded value: +"Filesystem path to the Magento project root (holds composer.json)."
- Changed
outdated_packages1 field changed- added
Input schema / properties / path / descriptionAdded value: +"Filesystem path to the Magento project root (holds composer.json)."
- Changed
project_status1 field changed- added
Input schema / properties / path / descriptionAdded value: +"Filesystem path to the Magento project root (holds composer.json)."
- Changed
security_audit1 field changed- added
Input schema / properties / path / descriptionAdded value: +"Filesystem path to the Magento project root (holds composer.json)."
- Changed
upgrade_plan3 fields changed- added
Input schema / properties / path / descriptionAdded value: +"Filesystem path to the Magento project root (holds composer.json)." - added
Input schema / properties / target_magento / descriptionAdded value: +"Target Magento version to check compatibility against, e.g. \"2.4.7\"." - added
Input schema / properties / target_php / descriptionAdded value: +"Target PHP version to check compatibility against, e.g. \"8.3\"."
3 tool updates
v0.3.0- Added
fleet_overview - Added
outdated_packages - Added
security_audit
5 tool updates
v0.1.0- First observed
check_updates - First observed
fetch_release_notes - First observed
module_risk - First observed
project_status - First observed
upgrade_plan
TDQS
Scored across 8 tools
The three audit-style tools (audit_security, check_outdated_packages, check_updates) sound similar but the descriptions explicitly contrast them (CVE advisories vs newer releases vs target-version compatibility), and build_upgrade_plan vs build_fleet_overview is also clarified as full-per-project vs batched subset. Only mild residual risk that a rushed agent picks check_updates when it means check_outdated_packages.
Every tool follows a consistent snake_case verb_noun pattern: get_project_status, audit_security, check_outdated_packages, scan_module_risk, build_fleet_overview, build_upgrade_plan, check_updates, fetch_release_notes. No mixed conventions or vague standalone verbs.
Eight tools is well-scoped for a Magento audit server: one fast overview, three independent composer-level checks, one code/static-analysis scanner, two planning tools at different granularities, and release-notes lookup. Each tool has a distinct role and none feels redundant.
The surface covers status overview, PHP/Magento compatibility, security advisories, outdated packages, static analysis, fleet triage, release notes, and a combined upgrade plan with clear blocker/unverified semantics. Minor gap: no remediation-oriented output (e.g., generated composer commands or patch suggestions), though that is arguably outside an audit-only server's scope.
Maintenance
Related MCP Connectors
Score a Magento or Adobe Commerce store on eight AI agent-readiness checks.
Code intelligence platform for AI agents. 20 tools for architecture, security & impact analysis.
Agent-readiness scanner (0-5 score), robots.txt + llms.txt generators, managed agent enablement.
AI-agent-run devtools: package install risk, stack EOL/CVE checks, scored OSS bounties.
Related MCP Servers
- AlicenseBqualityCmaintenanceEnables AI agents to interact with Magento 2 development environments through comprehensive tools for module management, database operations, cache control, configuration management, and system diagnostics. Supports complete development workflows from module creation to deployment and troubleshooting.2819 npm41MIT
- AlicenseBqualityCmaintenanceEnables AI assistants to manage Adobe Commerce and Magento 2 instances through business-level tools for catalog, promotions, CMS, and SEO. It features secure OAuth 1.0 authentication, safety guardrails for bulk operations, and built-in diagnostic reports for store health.3852 npm2MIT
- AlicenseBqualityDmaintenanceEnables AI agents to safely upgrade JavaScript and TypeScript projects through dependency analysis, upgrade path detection, breaking change identification, codemod application, and PR summary generation.141 npmMIT
- AlicenseAqualityCmaintenanceEnables AI agents to interact with Adobe Commerce Cloud projects via REST API and SSH for database queries, log reading, environment management, and more, with no PHP CLI required.1536 npmMIT