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.
- 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.phpkeys (passwords, secrets, hosts, ports, etc.) automatically masked - Curated critical-settings check (deployment mode, 2FA, MySQL optimizer, Xdebug/APCu, key rotation, …)
- 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 byrun_code_sniffer)
composer require freento/module-mcp-audit
php bin/magento module:enable Freento_McpAudit
php bin/magento setup:upgrade
php bin/magento cache:flushCopy 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:flushStores > 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.
| 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). |
| 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). |
| 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). |
| 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). |
| 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. |
| 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. |
| 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/*. |
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>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:
- The plugin reads
var/tmp/sql_counter/<id>.pending(created bycount_sql_querieswithaction=start). - Every call to
LoggerInterface::logStatsincrements an in-memory counter. Any SQL whose text contains the literal substringsql_counteris skipped as a defensive guard against self-counting. - On plugin instance teardown (
__destruct, end of request lifecycle), the result is written tovar/tmp/sql_counter/<id>.resultand the pending file is deleted. - A subsequent
count_sql_queriescall withaction=getreturns 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.
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.
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"}'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}}
}'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
}}
}'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
}}
}'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"]
}}
}'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"]
}}
}'# 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>"
}}
}'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
}}
}'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
}}
}'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
}}
}'MIT