{"_id":"@alex-engvall/laravel-debug-mcp","_rev":"2-c3a29a5ff201fa18a9406bd53fc1e796","name":"@alex-engvall/laravel-debug-mcp","dist-tags":{"next":"0.0.1-rc.1","latest":"0.1.0"},"versions":{"0.0.1-rc.1":{"name":"@alex-engvall/laravel-debug-mcp","version":"0.0.1-rc.1","license":"MIT","_id":"@alex-engvall/laravel-debug-mcp@0.0.1-rc.1","maintainers":[{"name":"alexengvall","email":"alexander.engvall@alemil.se"}],"bin":{"laravel-debug-mcp":"dist/cli.js","laravel-debug-mcp-server":"dist/index.js"},"dist":{"shasum":"324151259de5261709cb675fe507f3e000c26d32","tarball":"https://registry.npmjs.org/@alex-engvall/laravel-debug-mcp/-/laravel-debug-mcp-0.0.1-rc.1.tgz","fileCount":31,"integrity":"sha512-LiQHKejesDbI/1G17qnQq030klrHo6uwy9UGaAfT7M7pj0sS6Mz9NdBA/76WPtmTiMmAyUyUWFR3zBgIddvJzw==","signatures":[{"sig":"MEQCIBYvYEXEij9KehjzBIInOxeMXSVJ7peDe8sjP5rtwJVYAiAN6xIkNsYkncOLo67E+m482tm8z6CARH41EONuFthq+w==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":94042},"type":"module","engines":{"node":">=18.0.0"},"gitHead":"36271d8640a2e1ae2da39d008e38d480899efd85","private":false,"scripts":{"cli":"tsx src/cli.ts","dev":"tsx src/index.ts","lint":"eslint .","build":"tsc -p tsconfig.json","start":"node dist/index.js","format":"prettier -w .","prepack":"npm run build","typecheck":"tsc -p tsconfig.json --noEmit","release:verify":"node scripts/verify-release.mjs"},"_npmUser":{"name":"alexengvall","email":"alexander.engvall@alemil.se"},"_npmVersion":"11.7.0","description":"Interactive installer and production-safe MCP server for debugging Laravel apps via a hardened SSH diagnostic runner.","directories":{},"_nodeVersion":"24.12.0","dependencies":{"zod":"^3.25.0","dotenv":"^16.4.5","@modelcontextprotocol/sdk":"^1.25.0"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.19.2","eslint":"^9.8.0","prettier":"^3.3.3","typescript":"^5.6.3","@types/node":"^22.10.0"},"_npmOperationalInternal":{"tmp":"tmp/laravel-debug-mcp_0.0.1-rc.1_1780214270214_0.6517929859416991","host":"s3://npm-registry-packages-npm-production"}},"0.1.0":{"name":"@alex-engvall/laravel-debug-mcp","version":"0.1.0","private":false,"type":"module","description":"Interactive installer and production-safe MCP server for debugging Laravel apps via a hardened SSH diagnostic runner.","license":"MIT","repository":{"type":"git","url":"git+https://github.com/alex-engvall/laravel-debug-mcp.git"},"bugs":{"url":"https://github.com/alex-engvall/laravel-debug-mcp/issues"},"homepage":"https://github.com/alex-engvall/laravel-debug-mcp#readme","engines":{"node":">=18.0.0"},"scripts":{"build":"tsc -p tsconfig.json","dev":"tsx src/index.ts","cli":"tsx src/cli.ts","start":"node dist/index.js","typecheck":"tsc -p tsconfig.json --noEmit","lint":"eslint .","format":"prettier -w .","release:verify":"node scripts/verify-release.mjs","prepack":"npm run build"},"dependencies":{"@modelcontextprotocol/sdk":"^1.25.0","dotenv":"^16.4.5","zod":"^3.25.0"},"devDependencies":{"@types/node":"^22.10.0","eslint":"^9.8.0","prettier":"^3.3.3","tsx":"^4.19.2","typescript":"^5.6.3"},"bin":{"laravel-debug-mcp":"dist/cli.js","laravel-debug-mcp-server":"dist/index.js"},"gitHead":"dfd34ab733e2d3bd2e9a60be5aed94c53fc21627","_id":"@alex-engvall/laravel-debug-mcp@0.1.0","_nodeVersion":"22.22.3","_npmVersion":"11.16.0","dist":{"integrity":"sha512-QR3h1s1SWx+ktPTbHuKLJ42uqGPfQ67GxvfCiK19Ryn0MOQpZfHFEj7EGWsmQWgWr09Z5sOXWSVeNW/5CeMrqw==","shasum":"b0f42886ea31f440201e976fb09e85c4e9fff2ee","tarball":"https://registry.npmjs.org/@alex-engvall/laravel-debug-mcp/-/laravel-debug-mcp-0.1.0.tgz","fileCount":31,"unpackedSize":92817,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@alex-engvall%2flaravel-debug-mcp@0.1.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIDUMnDdNVh67DcMBQp/FtH2cmeuSP5se4bnsUuIIwvNOAiEAjAYS2XEikcU0G51I37+Qr2oVWMyTRqtcimaosLUclY4="}]},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:b5e777b6-f513-417f-be3a-09af6aa18abe"}},"directories":{},"maintainers":[{"name":"alexengvall","email":"alexander.engvall@alemil.se"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/laravel-debug-mcp_0.1.0_1780215778714_0.44439758192550727"},"_hasShrinkwrap":false}},"time":{"created":"2026-05-31T07:57:50.053Z","modified":"2026-05-31T08:22:59.197Z","0.0.1-rc.1":"2026-05-31T07:57:50.357Z","0.1.0":"2026-05-31T08:22:58.875Z"},"license":"MIT","description":"Interactive installer and production-safe MCP server for debugging Laravel apps via a hardened SSH diagnostic runner.","maintainers":[{"name":"alexengvall","email":"alexander.engvall@alemil.se"}],"readme":"# laravel-debug-mcp\n\nAn **installable CLI + production-safe MCP server** that lets **Codex CLI** run common Laravel diagnostics through a hardened SSH remote runner without granting interactive shell access.\n\n## Architecture\n\n- Codex CLI ⇄ local MCP server over stdio\n- local MCP server ⇄ SSH ⇄ `/usr/local/bin/laravel-diag`\n- `laravel-diag` executes a strict allowlist of diagnostics and returns JSON\n- SSH access can be restricted with an `authorized_keys` forced command\n\n## Quick start\n\nThe recommended setup path is the interactive installer:\n\n```bash\nnpx @alex-engvall/laravel-debug-mcp init\n```\n\nThe wizard asks for the profile name, server host, SSH setup user, Laravel app path, diagnostic user, SSH key choice, Codex configuration preference, and mutation policy. It then:\n\n1. creates or reuses a dedicated local Ed25519 key;\n2. connects to the server over SSH;\n3. creates the diagnostic user when needed;\n4. installs `/usr/local/bin/laravel-diag`;\n5. writes `/etc/laravel-diag.env` as `root:<diag-user>` with mode `0640`;\n6. installs the public key in `~<diag-user>/.ssh/authorized_keys` with a forced command;\n7. saves a local profile under `~/.config/laravel-debug-mcp/profiles/`;\n8. runs `codex mcp add` when Codex CLI is available;\n9. runs `doctor` smoke checks.\n\nYou can also install globally:\n\n```bash\nnpm install -g @alex-engvall/laravel-debug-mcp\nlaravel-debug-mcp init\n```\n\n## Non-interactive / CI setup\n\nUse `--config --yes` for repeatable setup from CI/CD or a checked-in non-secret config file:\n\n```bash\nlaravel-debug-mcp init --config ./laravel-debug-mcp.prod.json --yes\n```\n\nExample config:\n\n```json\n{\n  \"profile\": \"easytoday-prod\",\n  \"host\": \"app.easytoday.se\",\n  \"port\": 22,\n  \"setupUser\": \"root\",\n  \"diagUser\": \"codexdiag\",\n  \"appDir\": \"/home/easytoday/domains/app.easytoday.se/app\",\n  \"healthUrl\": \"http://127.0.0.1/up\",\n  \"enableMutations\": false,\n  \"codex\": {\n    \"configure\": true,\n    \"serverName\": \"laravelProdEasyToday\"\n  }\n}\n```\n\nKeep SSH private keys in your CI secret store. Do not commit secrets to this repository.\n\n## CLI commands\n\n```bash\nlaravel-debug-mcp init [--profile <name>] [--config <path>] [--yes] [--dry-run]\nlaravel-debug-mcp doctor --profile <name>\nlaravel-debug-mcp rotate-key --profile <name>\n```\n\n`rotate-key` generates a new per-profile key, installs it with the same forced-command bootstrap, updates the local profile and Codex MCP entry, runs `doctor`, and removes the previous public key from `authorized_keys` after verification.\n\n## Doctor checks\n\nAfter installation, run:\n\n```bash\nlaravel-debug-mcp doctor --profile easytoday-prod\n```\n\n`doctor` validates local prerequisites and performs remote smoke checks:\n\n- Node.js version;\n- SSH binary availability;\n- private key existence and permissions;\n- remote `sys.info` action;\n- Laravel `health` action;\n- `artisan.version` action.\n\n## Local profile format\n\nProfiles are written to:\n\n```text\n~/.config/laravel-debug-mcp/profiles/<profile>.json\n```\n\nA profile contains the host, port, diagnostic user, key path, remote command, mutation policy, output caps, timeout, and Codex server name. The MCP server still reads runtime configuration through `LARAVEL_PROD_*` environment variables, which makes Codex and CI integration straightforward.\n\n## Manual remote install\n\nThe full installer is preferred, but the legacy helper remains available:\n\n```bash\nsudo DIAG_USER=codexdiag scripts/remote/install-remote.sh\n```\n\nThen edit `/etc/laravel-diag.env` and configure SSH authorized keys manually. The full `init` flow does this automatically.\n\n## MCP server environment variables\n\nWhen running the MCP server directly, provide at least:\n\n```env\nLARAVEL_PROD_HOST=prod.example.com\nLARAVEL_PROD_USER=codexdiag\nLARAVEL_PROD_SSH_KEY=/home/alex/.ssh/laravel-debug-mcp/prod_ed25519\n```\n\nOptional variables:\n\n```env\nLARAVEL_PROD_SSH_PORT=22\nLARAVEL_PROD_REMOTE_COMMAND=/usr/local/bin/laravel-diag\nLARAVEL_PROD_TOOL_TIMEOUT_SEC=45\nLARAVEL_PROD_MAX_OUTPUT_CHARS=200000\nLARAVEL_PROD_ENABLE_MUTATIONS=0\n```\n\n## Available diagnostics\n\n### App / Laravel\n\n- `health`\n- `artisan_version`\n- `artisan_about`\n- `artisan_migrate_status`\n- `artisan_schedule_list`\n- `artisan_queue_failed`\n- `artisan_horizon_status`\n- `file_list`\n- `file_read`\n- `env_read`\n\n### Logs\n\n- `logs_list`\n- `logs_tail`\n- `logs_grep`\n- `logs_last_error`\n\n### System\n\n- `sys_info`\n- `sys_disk`\n- `sys_memory`\n- `sys_top`\n- `php_version`\n- `php_extensions`\n\n### Laravel cache artifacts\n\n- `cache_status`\n\n### Database read-only\n\n- `database_connections`\n- `database_schema`\n- `database_query` (`SELECT`, `SHOW`, `EXPLAIN`, and `DESCRIBE` only)\n\n### Break-glass mutations\n\nMutations are disabled by default and double-gated locally and remotely:\n\n1. local MCP config: `LARAVEL_PROD_ENABLE_MUTATIONS=1`\n2. remote runner config: `LARAVEL_DIAG_ENABLE_MUTATIONS=1`\n\nMutation tools:\n\n- `artisan_optimize_clear`\n- `artisan_config_cache`\n- `artisan_queue_restart`\n- `artisan_queue_retry`\n- `artisan_pulse_restart`\n\n## SSH hardening\n\nThe installer writes authorized keys in this form:\n\n```text\ncommand=\"/usr/local/bin/laravel-diag\",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty ssh-ed25519 AAAA...\n```\n\nThis makes OpenSSH run only the diagnostic runner for that key, even if the client asks for a shell or another command.\n\n## Development\n\n```bash\nnpm install\nnpm run typecheck\nnpm run build\nnode dist/cli.js --help\n```\n\n## Versioning\n\nCurrent version: `0.1.0`.\n\nKeep these version values in sync before every release:\n\n- `package.json`\n- `package-lock.json`\n- `src/cli.ts`\n- `src/index.ts`\n\nThe release verifier checks the package name, public package status, semver format, GitHub release tag, prerelease/stable release type, CLI version, and MCP server version:\n\n```bash\nnpm run release:verify\n```\n\nFor a release candidate, use a semver prerelease version such as `0.1.0` and publish the GitHub Release as a prerelease. For a stable release, use a plain semver version such as `0.0.1` and publish the GitHub Release as a stable release.\n\n## Release\n\nRelease checklist:\n\n1. Update the package version and matching source versions.\n2. Run local verification:\n\n   ```bash\n   npm ci\n   npm run release:verify\n   npm run typecheck\n   npm run build\n   npm pack --dry-run\n   ```\n\n3. Commit the release changes.\n4. Create and publish a GitHub Release whose tag is exactly `v<package.json version>`, for example `v0.1.0`.\n\nThe CI workflow runs on pull requests and pushes to `main`. It installs dependencies, verifies release metadata, typechecks, builds, and checks the package contents with `npm pack --dry-run`.\n\n## Publishing\n\nPublishing is handled by `.github/workflows/npm-publish.yml` when a GitHub Release is published.\n\nThe publish workflow:\n\n- verifies that the release tag matches `v<package.json version>`;\n- verifies that GitHub prereleases use semver prerelease versions;\n- verifies that stable GitHub releases use stable semver versions;\n- runs `npm run typecheck`;\n- checks package contents with `npm pack --dry-run`;\n- publishes to npm with provenance using `npm publish --access public --provenance`.\n\nGitHub prereleases are published to npm with the `next` dist-tag. Stable GitHub releases are published with the `latest` dist-tag.\n\nThe workflow expects npm trusted publishing/OIDC to be configured for `@alex-engvall/laravel-debug-mcp` because it uses `id-token: write` and does not read an npm token from repository secrets.\n","readmeFilename":"README.md","homepage":"https://github.com/alex-engvall/laravel-debug-mcp#readme","repository":{"type":"git","url":"git+https://github.com/alex-engvall/laravel-debug-mcp.git"},"bugs":{"url":"https://github.com/alex-engvall/laravel-debug-mcp/issues"}}