Interactive installer and production-safe MCP server for debugging Laravel apps via a hardened SSH diagnostic runner.
The server defines 29 Laravel debugging tools with mixed quality. Strong points: nearly all tools have descriptions and documented risk levels; schemas present for most tools with parameters; clear naming conventions (artisan_*, database_*, file_*, logs_*, sys_*, php_*). Weak points: descriptions are often terse (under 100 chars); parameter descriptions missing context on valid ranges/formats; no output schemas documented; no error handling guidance; no tool annotations (readOnlyHint/destructiveHint) despite clear risk levels noted separately. The codebase shows input validation (evidenced by maxLength/minLength constraints in schemas), but descriptions don't articulate format requirements clearly enough for LLM reasoning. Server targets production Laravel debugging via SSH, limiting scope appropriately, but tool definitions lack the polish expected for A-grade toolkits.
Run `php artisan about` (safe summary).
BREAK-GLASS: Run `php artisan config:cache` (rebuilds cached config). Disabled unless LARAVEL_PROD_ENABLE_MUTATIONS=1.
Run `php artisan horizon:status` (if Horizon installed).
Run `php artisan migrate:status`.
BREAK-GLASS: Run `php artisan optimize:clear` (clears config, route, view, event, and app caches). Disabled unless LARAVEL_PROD_ENABLE_MUTATIONS=1.
BREAK-GLASS: Run `php artisan pulse:restart` (if Pulse installed). Disabled unless LARAVEL_PROD_ENABLE_MUTATIONS=1.
Run `php artisan queue:failed`.
No tool annotations (readOnlyHint, destructiveHint, idempotentHint) despite explicit risk levels being declared separately. Server tracks risks (READ_ONLY, WRITE) in metadata but does not expose them as MCP 2.0 tool annotation hints. LLM cannot distinguish safe retry paths from destructive operations.
Parameter descriptions lack format constraints and valid ranges. Example: 'targets' in artisan_queue_retry says 'Job IDs to retry or all' but does not document delimiter rules (space vs comma) or format of job IDs. Parameter 'query' in database_query (max 5000 chars) has no guidance on read-only enforcement mechanism, LLM must infer.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | C | 63 | 2026-07-28+ | v2 |
BREAK-GLASS: Run `php artisan queue:restart` (signals workers to restart after current job). Disabled unless LARAVEL_PROD_ENABLE_MUTATIONS=1.
BREAK-GLASS: Run `php artisan queue:retry <ids|all>`. Pass `targets` as `all` (default) or a list of failed job IDs separated by spaces/commas. Disabled unless LARAVEL_PROD_ENABLE_MUTATIONS=1.
Run `php artisan schedule:list`.
Run `php artisan --version`.
Inspect Laravel cache artifacts (bootstrap/cache/*.php) with mtimes and sizes (no secrets).
List configured Laravel database connection names and identify the default connection.
Execute a read-only SQL query (SELECT/SHOW/EXPLAIN/DESCRIBE only) against a Laravel DB connection.
Read database schema details for a connection (tables, columns, indexes, foreign keys).
Read a Laravel app `.env*` file from app root (default `.env`). Output is best-effort redacted.
List files/directories under Laravel app root. Use optional relative `path`, recursive mode, and output cap.
Read any file under Laravel app root. Use a relative path like `app/Models/User.php` or `.env`.
Check Laravel's health endpoint (default: http://127.0.0.1/up) from the server.
Search Laravel log file for a literal string (fixed-string grep).
Heuristic: show the last lines in the log that look like ERROR/CRITICAL/Exception. Good first stop.
List available Laravel log files (storage/logs) with size and modified time.
Tail Laravel log file. By default tails the most recently modified log file.
List loaded PHP extensions (php -m).
Show PHP CLI version.
Disk usage (df -h).
Basic system info: uname, date, uptime, load, whoami.
Memory usage (free -m or /proc/meminfo).
Top processes (ps snapshot, not interactive).
No output schemas documented. Tool descriptions state what they do but responses are not described, LLM cannot plan downstream tool chaining. Example: 'database_schema' returns tables, columns, indexes, but no field names documented. 'logs_tail' returns lines but not structure (plain text vs JSON vs structured entries).
Error handling not documented. No guidance on what happens when a tool fails (e.g., invalid SQL query, missing log file, permission denied on file read). LLM receives raw error but has no recovery path or retry strategy.
Tool descriptions too terse to guide LLM selection. Many tools (sys_info, sys_disk, sys_memory, sys_top, php_version, php_extensions) have 10-20 char descriptions that fail to explain WHEN to call them or what differentiates them from alternatives.
No pagination guidance. Tools like 'database_schema' (maxTables=100 default), 'logs_tail' (lines=200 default), and 'logs_grep' (maxMatches=200 default) cap results but descriptions do not explain truncation behavior or how to retrieve additional results.
Missing required parameters for mutating tools. 'artisan_optimize_clear', 'artisan_config_cache', 'artisan_queue_restart', 'artisan_pulse_restart' have no parameters but descriptions note they require LARAVEL_PROD_ENABLE_MUTATIONS=1 environment variable. No input schema to indicate preconditions or to allow user confirmation before execution.
Secrets redaction strategy in responses not documented. env_read tool says 'Output is best-effort redacted' but does not specify which patterns are redacted or when redaction might fail. LLM cannot reason about secret leakage risk.