Laraguard MCP
# Laraguard MCP
<img width="100%" alt="image" src="https://github.com/user-attachments/assets/27731e3b-2a15-4b1a-b2e3-c76fca96fff5" />
> **A security audit MCP server for Laravel projects β built with TypeScript and stdio transport.**
[](./LICENSE)
[](https://nodejs.org/)
[](https://www.typescriptlang.org/)
[](https://github.com/modelcontextprotocol/sdk)
[](./package.json)
---
## Overview
**Laraguard MCP** is a standalone [Model Context Protocol (MCP)](https://modelcontextprotocol.io/) server that performs security audits on Laravel projects. It is implemented in pure TypeScript using the official `@modelcontextprotocol/sdk` and communicates over **stdio**, making it natively compatible with any MCP-capable IDE or client (Cursor, Claude Desktop, VS Code MCP extensions, etc.).
The server analyses a Laravel project as an **external target** β it does not require Laravel to be running. It returns structured JSON findings categorised by severity, covering configuration issues, risky code patterns, and dependency hygiene.
---
## Features
- π **Static code scanning** β 15+ rules covering SQL injection, RCE, hardcoded credentials, weak crypto, mass assignment, and LFI
- π **Blade XSS scanner** β detects unescaped `{!! !!}` output and raw input rendering in templates
- π£οΈ **Route & middleware audit** β flags admin routes without auth, API routes without auth:sanctum, login routes without throttle, and CSRF exceptions
- π¦ **Dependency CVE feed** β queries the [OSV.dev](https://osv.dev/) API for real CVEs across all `composer.lock` packages
- βοΈ **Configuration audit** β inspects `.env` (DEBUG, APP_KEY, APP_ENV, secure cookies) and `config/cors.php`
- ποΈ **Project metadata** β reads `composer.json` to identify Laravel and PHP version constraints
- π₯ **Active attack simulation** β fires HTTP probes (SQL injection, XSS, CSRF, auth bypass, rate limiting) against a running app
- π **Path traversal prevention** β strict allowlist enforcement for all file operations
- βοΈ **Secret redaction** β sensitive values are masked in textual output before reaching the MCP client
- π **stdio transport** β zero-config network; works inside any IDE that supports MCP
---
## MCP Tools
The server exposes **8 tools**. All static tools accept a single `path` parameter. `attack_simulate` additionally requires a `baseUrl`.
| Tool | Input | Description |
|------|-------|-------------|
| `project_info` | `path` | Returns metadata from `composer.json`: project name, Laravel/PHP version constraints, engine info. |
| `dependency_audit` | `path` | Parses `composer.lock` and queries **OSV.dev** for real CVEs with severity and fix versions. |
| `config_audit` | `path` | Inspects `.env` (DEBUG, APP_KEY, APP_ENV, session cookies) and `config/cors.php` (wildcard origins). |
| `code_scan` | `path` | 15+ static pattern rules across all PHP files β credentials, weak crypto, mass assignment, RCE, LFI, SQL injection. |
| `blade_scan` | `path` | Scans `resources/views/` Blade templates for unescaped output (`{!! !!}`) and XSS-prone patterns. |
| `route_audit` | `path` | Audits route files and middleware for missing auth, missing throttle, and CSRF exception wildcards. |
| `attack_simulate` | `path` + `baseUrl` | Fires 6 live HTTP probes against a running app: SQL injection, XSS, CSRF, auth bypass, rate limiting, error disclosure. |
| `full_audit` | `path` | Runs `dependency_audit` + `config_audit` + `code_scan` + `blade_scan` + `route_audit` in parallel and returns a consolidated report. |
### Code Scan β Detected Patterns
| Pattern | Severity | Finding Type |
|---------|----------|--------------|
| `->whereRaw(` | High | `SQL_INJECTION` |
| `DB::raw(` | Medium | `RAW_SQL_USAGE` |
| `unserialize(` | Critical | `UNSAFE_UNSERIALIZE` |
| `shell_exec(` / `exec(` / `system(` / `passthru(` | Critical | `RCE_RISK` |
| `eval(` | Critical | `EVAL_USAGE` |
| `password = 'literal'` | Critical | `HARDCODED_PASSWORD` |
| `api_key = 'literal'` | Critical | `HARDCODED_API_KEY` |
| Long hardcoded tokens/secrets | High | `HARDCODED_SECRET` |
| `md5(` | High | `WEAK_HASH_MD5` |
| `sha1(` | Medium | `WEAK_HASH_SHA1` |
| `protected $guarded = []` | High | `MASS_ASSIGNMENT_UNGUARDED` |
| `file_get_contents($requestβ¦)` | Critical | `PATH_TRAVERSAL_RISK` |
| `include/require($requestβ¦)` | Critical | `LFI_RISK` |
### Audit Report Schema
Every tool returns a structured JSON report:
```json
{
"summary": {
"critical": 0,
"high": 1,
"medium": 2,
"low": 0,
"info": 1
},
"findings": [
{
"severity": "high",
"type": "SQL_INJECTION",
"title": "Potential SQL injection via whereRaw",
"file": "app/Http/Controllers/UserController.php",
"line": 42,
"evidence": "->whereRaw('email = ' . $email)",
"recommendation": "Avoid raw SQL with user input. Use parameter binding/query builder."
}
],
"metadata": {
"scannedPath": "/absolute/path/to/laravel-project",
"engine": "Laraguard MCP",
"version": "3.0.0",
"timestamp": "2025-01-01T00:00:00.000Z",
"durationMs": 312
}
}
```
---
## Architecture
```
src/
βββ index.ts β MCP server bootstrap and tool registration
βββ config.ts β Environment variable loading and validation
βββ security.ts β Path allowlist enforcement and secret redaction
βββ files.ts β Safe file enumeration and reading
βββ tools.ts β Audit tool implementations
βββ reports.ts β Report aggregation and severity summarization
βββ types.ts β Domain types (Finding, AuditReport, Severity, etc.)
```
**Runtime stack:**
| Component | Technology |
|-----------|------------|
| Runtime | Node.js 20+ |
| Language | TypeScript 5.x |
| Protocol | Model Context Protocol (MCP) |
| Transport | `stdio` |
| Schema validation | Zod |
| MCP SDK | `@modelcontextprotocol/sdk` |
---
## Requirements
- **Node.js** 20 or higher
- **npm** 10 or higher
Verify your environment:
```bash
node -v
npm -v
```
---
## Installation
Clone the repository and install dependencies:
```bash
git clone https://github.com/ecr17dev/Laraguard-MCP.git
cd "Laraguard MCP"
npm install
```
---
## Configuration
Copy the example environment file and customise it:
```bash
cp .env.example .env
```
### Environment Variables
| Variable | Default | Description |
|----------|---------|-------------|
| `MCP_BASE_PATH` | β | Single allowed root path for project scanning. |
| `MCP_BASE_PATHS` | β | Comma-separated list of allowed root paths. **Takes precedence** over `MCP_BASE_PATH`. |
| `MCP_MAX_FILES` | `5000` | Maximum number of files to enumerate per scan. |
| `MCP_MAX_FILE_SIZE_BYTES` | `300000` | Maximum file size (in bytes) to read per file. |
| `MCP_TIMEOUT_SECONDS` | `30` | Logical timeout for audit operations. |
> **Priority order:** `MCP_BASE_PATHS` β `MCP_BASE_PATH` β current working directory.
### Example `.env`
```env
# Allow scanning two project roots
MCP_BASE_PATHS="/Users/yourname/projects/my-laravel-app,/srv/workspaces/api"
# Scan limits
MCP_MAX_FILES=5000
MCP_MAX_FILE_SIZE_BYTES=300000
MCP_TIMEOUT_SECONDS=30
```
---
## Development
### Available Scripts
| Command | Description |
|---------|-------------|
| `npm run dev` | Runs the MCP server directly from TypeScript source using `tsx` (recommended for development) |
| `npm run build` | Compiles TypeScript to `dist/` |
| `npm run start` | Runs the compiled server from `dist/index.js` |
| `npm run check` | Type-checks the project without emitting output |
### Running in Development Mode
```bash
npm run dev
```
### Building for Production
```bash
npm run check # Validate types first
npm run build # Emit to dist/
npm run start # Run compiled output
```
---
## Integration with MCP Clients
### Generic MCP Configuration (JSON)
Add the following to your MCP client's configuration file, replacing the path with the absolute path to your installation:
```json
{
"mcpServers": {
"laraguard": {
"command": "node",
"args": ["/absolute/path/to/Laraguard MCP/dist/index.js"],
"env": {
"MCP_BASE_PATHS": "/absolute/path/to/your-laravel-project"
}
}
}
}
```
### Using Development Mode (tsx)
If you prefer to run without building first:
```json
{
"mcpServers": {
"laraguard": {
"command": "npx",
"args": ["tsx", "/absolute/path/to/Laraguard MCP/src/index.ts"],
"env": {
"MCP_BASE_PATHS": "/absolute/path/to/your-laravel-project"
}
}
}
}
```
### Cursor IDE
Open **Settings β MCP** and paste the JSON block above. Cursor will detect the server on the next reload.
### Claude Desktop
Edit `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) and add the `laraguard` entry under `mcpServers`.
---
## Tool Usage Reference
### `project_info`
```json
{ "path": "/absolute/path/to/laravel-project" }
```
Returns basic project metadata without performing any security checks. Use it to confirm the target is a valid Laravel project and inspect framework and PHP version constraints before auditing.
---
### `dependency_audit`
```json
{ "path": "/absolute/path/to/laravel-project" }
```
Parses `composer.lock`, extracts all locked package names and versions, and queries the **[OSV.dev](https://osv.dev/) batch API** for known CVEs. Each vulnerability is returned as a finding with:
- CVE/GHSA identifier and summary
- Severity (mapped from CVSS score)
- Affected package version and recommended fix version
- Direct link to the advisory page
---
### `config_audit`
```json
{ "path": "/absolute/path/to/laravel-project" }
```
| Check | File | Severity |
|-------|------|----------|
| `APP_DEBUG=true` | `.env` | High |
| `APP_ENV=local` | `.env` | Medium |
| `APP_KEY=` (empty) | `.env` | Critical |
| `SESSION_SECURE_COOKIE=false` | `.env` | Medium |
| Wildcard CORS origin (`'*'`) | `config/cors.php` | Medium |
---
### `code_scan`
```json
{ "path": "/absolute/path/to/laravel-project" }
```
Performs line-by-line static analysis across all PHP files. Returns every matching finding with file path, line number, and evidence snippet. See the [Code Scan β Detected Patterns](#code-scan--detected-patterns) table above for the full rule set.
---
### `blade_scan`
```json
{ "path": "/absolute/path/to/laravel-project" }
```
Scans all `.blade.php` files under `resources/views/` for XSS-prone output patterns:
| Check | Severity |
|-------|----------|
| `{!! $variable !!}` β unescaped variable | High |
| `{!! request( !!}` / `{!! old( !!}` β raw user input | Critical |
| `echo $_GET` / `echo $_POST` in blade PHP blocks | High |
---
### `route_audit`
```json
{ "path": "/absolute/path/to/laravel-project" }
```
Reads `routes/web.php`, `routes/api.php`, and `app/Http/Middleware/VerifyCsrfToken.php`:
| Check | File | Severity |
|-------|------|----------|
| Admin/dashboard route without `auth` middleware | `routes/web.php` | Critical |
| API route without `auth:sanctum` / `auth:api` | `routes/api.php` | High |
| Login/register route without `throttle` middleware | Route files | Medium |
| Wildcard pattern in `VerifyCsrfToken::$except` | `VerifyCsrfToken.php` | High |
---
### `attack_simulate`
```json
{
"path": "/absolute/path/to/laravel-project",
"baseUrl": "http://localhost:8000"
}
```
> β οΈ **Only use against local or staging environments. Never run against production.**
Fires 6 live HTTP probes against the running application:
| Probe | Method & Endpoint | What it Tests |
|-------|------------------|---------------|
| `error_disclosure` | `GET /__invalid_route__` | Framework/stack-trace info leakage |
| `sql_injection_login` | `POST /login` with SQLi payload | SQL injection in login form |
| `reflected_xss` | `GET /search?q=<script>β¦` | Reflected XSS in search/query params |
| `csrf_not_enforced` | `POST /login` without CSRF token | CSRF token enforcement (expects HTTP 419) |
| `auth_bypass` | `GET /api/user` without auth header | Unauthenticated access to protected API |
| `rate_limit` | 10Γ rapid `POST /login` | Brute-force rate limiting (expects HTTP 429) |
The report includes a `probes` metadata array with the status code, duration, and triggered state for every probe.
---
### `full_audit`
```json
{ "path": "/absolute/path/to/laravel-project" }
```
Runs `dependency_audit`, `config_audit`, `code_scan`, `blade_scan`, and `route_audit` **in parallel** and merges all findings into a single consolidated report. The metadata includes per-section summaries.
---
## Security Design
Laraguard MCP implements the following controls to ensure it operates safely even when handling untrusted project paths:
- **Strict path allowlisting** β all file access is validated against `MCP_BASE_PATHS` / `MCP_BASE_PATH`; path traversal attempts are rejected immediately.
- **File count limit** β configurable cap (`MCP_MAX_FILES`) prevents runaway enumeration on large monorepos.
- **File size limit** β configurable cap (`MCP_MAX_FILE_SIZE_BYTES`) prevents memory exhaustion from binary or generated files.
- **Directory and extension exclusions** β `vendor/`, `node_modules/`, `.git/`, and binary file types are excluded from scans.
- **Secret redaction** β sensitive values (passwords, tokens, keys) are masked in textual output before being returned to the MCP client.
- **Attack simulation guard** β `attack_simulate` always targets only the explicitly provided `baseUrl`; no automated discovery or production detection is performed.
---
## Important Notes
- Laraguard MCP analyses a Laravel project **as an external auditor** β the Laravel application itself does not need to be running for static tools.
- `attack_simulate` **requires** the application to be running and should never target production.
- The server is **framework-agnostic at the transport level**: any client that supports MCP stdio can use it.
- All findings are informational. Always combine automated scanning with manual code review and dedicated DAST/SAST tooling (OWASP ZAP, Burp Suite) for production security assessments.
---
## License
This project is licensed under the **MIT License**. See [LICENSE](./LICENSE) for details.
TDQS
Scored across 8 tools
Each tool has a clearly distinct purpose with no overlap: attack_simulate runs active probes, blade_scan focuses on Blade templates, code_scan analyzes PHP source, config_audit checks environment settings, dependency_audit reviews Composer dependencies, full_audit consolidates other audits, project_info provides metadata, and route_audit examines route configurations. The descriptions explicitly differentiate their scopes, eliminating any ambiguity.
All tool names follow a consistent snake_case pattern with clear verb_noun structures: attack_simulate, blade_scan, code_scan, config_audit, dependency_audit, full_audit, project_info, and route_audit. The naming is predictable and readable throughout, with no deviations in style or convention.
With 8 tools, the set is well-scoped for Laravel security auditing, covering active testing, static analysis, dependency checks, configuration reviews, and metadata. Each tool earns its place by addressing a specific aspect of security, avoiding redundancy while providing comprehensive coverage for the domain.
The tool surface offers complete coverage for Laravel security auditing: it includes active simulation (attack_simulate), static analysis (code_scan, blade_scan), configuration auditing (config_audit, route_audit), dependency management (dependency_audit), a consolidated audit option (full_audit), and project metadata (project_info). There are no obvious gaps, and the tools support a full security assessment workflow from start to finish.