freento/module-mcp-audit

MCP Audit Tools for Magento 2

Maintainers

Package info

github.com/Freento/MCPAudit

Type:magento2-module

pkg:composer/freento/module-mcp-audit

Statistics

Installs: 0

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

1.0.0 2026-05-27 15:52 UTC

This package is auto-updated.

Last update: 2026-05-27 15:57:27 UTC


README

Add-on for Freento_Mcp that registers a set of audit and diagnostic MCP tools. The tools are designed for AI-driven store audits — collecting structured data about the filesystem, database, configuration, logs, indexers, cron, third-party modules, code quality and email delivery, all exposed over the standard MCP protocol provided by Freento_Mcp.

Features

  • 16 ready-to-use audit tools registered into the parent module's ToolRegistry
  • Single admin toggle to hide every audit tool everywhere (tools/list, tools/call, ACL UI)
  • Log error grouping with smart message normalization (UUIDs, IDs, quoted values, emails)
  • Two-step on-demand SQL query counter for any frontend URL (bypasses FPC)
  • Sensitive env.php keys (passwords, secrets, hosts, ports, etc.) automatically masked
  • Curated critical-settings check (deployment mode, 2FA, MySQL optimizer, Xdebug/APCu, key rotation, …)

Requirements

  • Magento 2.4.x
  • PHP 8.1+
  • freento/module-mcp ^1.2 (loaded as a module sequence dependency)
  • magento/magento-coding-standard (declared as a composer dependency; required by run_code_sniffer)

Installation

Via Composer

composer require freento/module-mcp-audit
php bin/magento module:enable Freento_McpAudit
php bin/magento setup:upgrade
php bin/magento cache:flush

Manual

Copy the module to app/code/Freento/McpAudit/ and run:

php bin/magento module:enable Freento_McpAudit
php bin/magento setup:upgrade
php bin/magento cache:flush

Configuration

Stores > Configuration > Freento > MCP > MCP Audit

Field Path Description
Enable Audit Tools freento_mcp/audit/enabled When disabled, all McpAudit tools are hidden everywhere — they are not exposed via tools/list, cannot be called, and do not appear in the ACL Rule tools list.

The toggle is enforced at the ToolRegistry level via Plugin\ToolRegistryPlugin, which filters out every tool whose class lives under the Freento\McpAudit\ namespace when the module is disabled.

Available Tools

Database & Filesystem

Tool Description
get_table_sizes Database table sizes (rows + MB) sorted by size, with optional LIKE pattern, min-size and limit filters.
get_log_file_sizes Files in var/log and var/report sorted by size, with each file's inode change time (ctime).

Logs & Errors

Tool Description
get_log_errors Greps var/log/*.log for ERROR/CRITICAL entries, groups identical errors after normalizing UUIDs, IDs, quoted strings and emails. Filterable by date range (silently truncated to the first 31 days starting at from_date), sortable by count/first_seen/last_seen. Defaults: from_date/to_date = today, limit = 50 (max 200).

Indexers & Cron

Tool Description
get_indexer_statuses All indexers with status (valid/invalid/working), mode (schedule/save) and changelog backlog count.
get_cron_config Cron groups configuration: schedule/lifetime/cleanup settings (XML defaults vs DB overrides), use_separate_process flag, and per-group job list with cron expressions.
get_cron_schedule Cron schedule history (cron_schedule table) with filtering, sorting and aggregation, plus a derived execution_time field (finished_at - executed_at, rendered as a human-readable duration like 5m 30s).

Configuration

Tool Description
get_critical_settings Curated checks that are awkward to express via the generic config tools: deployment mode, admin URL, 2FA status, active cart rules without a coupon (always-on rules), MySQL optimizer_switch / optimizer_use_condition_selectivity, Xdebug + APCu state, search terms count, presence of an active admin user, and whether the encryption key has been rotated.
get_config_data Fully resolved ScopeConfigInterface values (config.xml + core_config_data + env.php overrides). Accepts exact paths or path prefixes; supports default/websites/stores scopes and all_scopes: true for a full dump.
get_php_ini_settings ini_get() lookup for an explicit list of php.ini directives.
get_deployment_config Values from app/etc/env.php for an explicit paths list. Sensitive entries are silently omitted — match either a substring (password, passwd, secret, token, crypt, salt, private, credential, api_key, access_key, bearer, oauth, signature, hmac) or a full path segment (host, port, server, dbname, username, user, pwd, pass, key, auth, pem, cert).

Modules & Code Quality

Tool Description
get_third_party_modules Installed non-Magento and non-PayPal modules grouped by vendor, with composer name and install location (app/code vs vendor/). Optional include_latest_version queries the configured composer repositories for available stable upgrades.
run_code_sniffer Runs vendor/bin/phpcs --standard=Magento2 against a module name (Vendor_Module), relative path, or absolute path. Output is parsed from JSON, filtered by severity, capped at 200 KB, and grouped per file.

Catalog & Customer

Tool Description
get_customer_groups customer_group rows with filtering and aggregation (entity-tool framework).
get_eav_attributes eav_attribute rows with filtering by entity type, backend type, frontend input, native vs user-defined.

Performance & Email

Tool Description
count_sql_queries Counts SQL queries executed for an arbitrary storefront URL (the SqlCounterPlugin is registered in the frontend area only — admin/API requests are not counted). Two-step flow: action=start returns a counter ID and a visit URL containing ?_sql_counter=<id>; visiting that URL triggers the plugin (FPC bypassed by the unique query string); action=get returns the count.
send_test_email Sends a test email through the configured customer-create-account template, using the store's transactional sender. Useful for verifying SMTP and trans_email/ident_general/*.

Architecture

How tools are registered

etc/di.xml extends the parent module's Freento\Mcp\Model\ToolRegistry constructor's tools array argument, plus attaches ToolRegistryPlugin:

<type name="Freento\Mcp\Model\ToolRegistry">
    <arguments>
        <argument name="tools" xsi:type="array">
            <item name="get_table_sizes" xsi:type="object">Freento\McpAudit\Model\Tool\GetTableSizes</item>
            <!-- … 15 more entries … -->
        </argument>
    </arguments>
    <plugin name="freento_mcp_audit_tool_registry"
            type="Freento\McpAudit\Plugin\ToolRegistryPlugin"
            sortOrder="100"/>
</type>

How the SQL counter works

Plugin\SqlCounterPlugin is wired (in etc/frontend/di.xml, frontend area only) as a before plugin on Magento\Framework\DB\LoggerInterface::logStats. When a storefront request includes the _sql_counter=<id> parameter:

  1. The plugin reads var/tmp/sql_counter/<id>.pending (created by count_sql_queries with action=start).
  2. Every call to LoggerInterface::logStats increments an in-memory counter. Any SQL whose text contains the literal substring sql_counter is skipped as a defensive guard against self-counting.
  3. On plugin instance teardown (__destruct, end of request lifecycle), the result is written to var/tmp/sql_counter/<id>.result and the pending file is deleted.
  4. A subsequent count_sql_queries call with action=get returns the result and cleans up.

The _sql_counter parameter doubles as a cache-busting query string, so the counted response is guaranteed not to be served from FPC.

API Reference

All tools are invoked through the parent Freento_Mcp JSON-RPC endpoint (/freento_mcp/index/index). The audit module only adds tools — the request format, authentication, and transport are documented in the parent module README.

List audit tools

tools/list returns every registered tool; audit tools are the ones whose names appear in the table above.

curl -X POST https://your-store.com/freento_mcp/index/index \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <token>" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'

Call an audit tool

get_table_sizes — top 10 largest tables

curl -X POST https://your-store.com/freento_mcp/index/index \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <token>" \
  -d '{
        "jsonrpc":"2.0","id":2,"method":"tools/call",
        "params":{"name":"get_table_sizes","arguments":{"limit":10}}
      }'

get_log_errors — grouped errors for a date range

curl -X POST https://your-store.com/freento_mcp/index/index \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <token>" \
  -d '{
        "jsonrpc":"2.0","id":3,"method":"tools/call",
        "params":{"name":"get_log_errors","arguments":{
          "from_date":"2026-04-01","to_date":"2026-04-30",
          "sort_by":"count","sort_dir":"desc","limit":20
        }}
      }'

get_config_data — read a subtree across all scopes

curl -X POST https://your-store.com/freento_mcp/index/index \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <token>" \
  -d '{
        "jsonrpc":"2.0","id":4,"method":"tools/call",
        "params":{"name":"get_config_data","arguments":{
          "paths":["dev/css","dev/js"],"all_scopes":true
        }}
      }'

get_deployment_config — values from app/etc/env.php

Sensitive segments (password, host, dbname, …) are silently omitted.

curl -X POST https://your-store.com/freento_mcp/index/index \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <token>" \
  -d '{
        "jsonrpc":"2.0","id":5,"method":"tools/call",
        "params":{"name":"get_deployment_config","arguments":{
          "paths":["session/save","cache"]
        }}
      }'

get_php_ini_settings

curl -X POST https://your-store.com/freento_mcp/index/index \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <token>" \
  -d '{
        "jsonrpc":"2.0","id":6,"method":"tools/call",
        "params":{"name":"get_php_ini_settings","arguments":{
          "keys":["memory_limit","max_execution_time",
                  "opcache.memory_consumption","opcache.validate_timestamps"]
        }}
      }'

count_sql_queries — two-step flow

# 1. Start: get a counter ID and a visit URL
curl -X POST https://your-store.com/freento_mcp/index/index \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <token>" \
  -d '{
        "jsonrpc":"2.0","id":7,"method":"tools/call",
        "params":{"name":"count_sql_queries","arguments":{
          "action":"start","url":"https://your-store.com/"
        }}
      }'

# 2. Visit the returned URL (browser or curl). The _sql_counter param bypasses FPC.
curl -s "https://your-store.com/?_sql_counter=<counter_id>" >/dev/null

# 3. Get the result
curl -X POST https://your-store.com/freento_mcp/index/index \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <token>" \
  -d '{
        "jsonrpc":"2.0","id":8,"method":"tools/call",
        "params":{"name":"count_sql_queries","arguments":{
          "action":"get","counter_id":"<counter_id>"
        }}
      }'

run_code_sniffer

curl -X POST https://your-store.com/freento_mcp/index/index \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <token>" \
  -d '{
        "jsonrpc":"2.0","id":9,"method":"tools/call",
        "params":{"name":"run_code_sniffer","arguments":{
          "path":"Freento_McpAudit","severity":"errors","limit":50
        }}
      }'

send_test_email

curl -X POST https://your-store.com/freento_mcp/index/index \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <token>" \
  -d '{
        "jsonrpc":"2.0","id":10,"method":"tools/call",
        "params":{"name":"send_test_email","arguments":{
          "email":"qa@example.com","store_id":1
        }}
      }'

Entity-list tools (get_cron_schedule, get_customer_groups, get_eav_attributes)

These extend the parent module's entity-tool framework, so they accept the same filters / function / field / group_by / limit / sort_by / sort_dir parameters as the rest of Freento_Mcp (see parent README — Filters / Aggregation).

# Failed cron jobs in the last 7 days, grouped by job_code
curl -X POST https://your-store.com/freento_mcp/index/index \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <token>" \
  -d '{
        "jsonrpc":"2.0","id":11,"method":"tools/call",
        "params":{"name":"get_cron_schedule","arguments":{
          "filters":{
            "status":{"in":["error","missed"]},
            "scheduled_at":{"gte":"2026-04-29"}
          },
          "function":"count","group_by":"job_code","limit":20
        }}
      }'

License

MIT