stubbedev/laravel-dev-mcp
Model Context Protocol server for Laravel that gives AI assistants like Claude structured access to your app's routes, models, config, logs and Artisan commands, so they can inspect, query and debug a codebase directly from the editor chat. Built for local development workflows.
composer require --dev stubbedev/laravel-dev-mcp
php artisan vendor:publish --tag="dev-mcp-config" (confirm the exact tag in vendor/stubbedev/laravel-dev-mcp/config/ — this package may register the tag as dev-mcp or laravel-dev-mcp).{
"mcpServers": {
"my-app": {
"command": "php",
"args": ["artisan", "mcp:serve"],
"cwd": "/absolute/path/to/my-app"
}
}
}
If the package exposes an HTTP/SSE transport instead, use the published route (check routes/ or the README) and point the client at it.config/dev-mcp.php (tool allowlist and toggles), src/Tools/ (the actual capabilities and their input schemas), the composer.json require block (Laravel/PHP version floor), and the README's transport section.artisan route:list | grep and grep -r archaeology. Ask the agent for something narrow and verifiable — "list the routes under /api/orders, then show the signature of the controller methods they point at" or "which migrations created the invoices table and what columns exist now?" — and compare the answer to php artisan route:list / the migration files until you trust the tool output.Release note: v0.0.17 is a patch bump (the changelog is only a compare link, no described changes). Treat it as a bugfix drop with no migration steps; pin ^0.0.17 and read the diff at the link above before crossing into a 0.1.x minor.
Read-first, write-never for the agent. The highest-value tools in a Laravel dev MCP server are introspection: routes, model/schema shape, config values, log tails, artisan command lists, container bindings. Wire your client config so the agent reaches for these before it starts guessing at file paths. A typical debugging loop:
laravel.log and group the exceptions by class."Each step replaces a shell round-trip the agent would otherwise fumble.
One server entry per project. Don't try to make a single global registration serve multiple apps. Each MCP client entry should be scoped with its own cwd and its own env, so tools resolve routes/config/models against the right codebase. Prefix the server name with the app (billing-api, admin-portal) so the agent can pick deliberately.
Scope tools by environment in config. Enable the broad, mutating-capable tools (tinker, arbitrary artisan execution) only for an APP_ENV=local entry. For a shared staging config, restrict to read-only tools via the package's allowlist. Two client entries pointing at the same repo with different tool sets is cheaper than auditing every prompt.
Team-shareable client config. Commit a .mcp.json (or a documented snippet in the README) with relative or $PWD-based paths and no secrets. Every developer then gets the same tool surface, and the agent stops behaving differently per machine.
Pair it with tests, don't replace them. Use the MCP server to locate and explain code, then have the agent run php artisan test --filter=.... Introspection tools tell you what the app is configured to do; only the test run tells you what it actually does. In practice the useful prompt shape is "find the failing behaviour with the route/model tools, then write a test that reproduces it, then fix it."
Use it as a schema oracle during migrations and refactors. Before a rename, ask the agent to enumerate every place a column is referenced using the model/schema tools — cheaper than a blind grep, and it catches accessors, casts, and factory definitions.
Extension point. If your app has domain concepts the package doesn't know about (feature flags, a custom permission registry), register your own tool in an AppServiceProvider/dedicated provider against the package's tool registry. Keep custom tools read-only and side-effect-free.
.env/config will happily hand your APP_KEY, DB credentials, and third-party API keys to whatever model is on the other end. Never register the server against a production checkout, and belt-and-braces it with an APP_ENV !== 'production' guard in the service provider.composer update or any change to the package, restart the MCP client — otherwise you're debugging against a stale process from the previous version.cwd is the most common failure. Launched from the wrong directory, php artisan fails or, worse, resolves a different Laravel app. Use an absolute path in the client config and verify with a trivial prompt ("what's the app name?").php. If the app runs in Sail, the entry needs sail artisan mcp:serve, not the host binary — mismatched extensions produce confusing startup crashes.config:cache freezes the published config. Edit config/dev-mcp.php, run php artisan config:clear, then restart the client. A cached config plus a restarted client is the classic "my allowlist change did nothing."artisan generally don't handle migrate:fresh prompts or queue:work. Keep a timeout on the tool call and avoid anything that streams output indefinitely.storage/logs/laravel.log can be hundreds of MB. Always tail/limit; a tool that reads the whole file will blow the model's context window and your token budget in one call. Rotated daily logs are worse — confirm which file the tool resolves to.artisan make:*, cache clears) leaves the repo in a state the next prompt didn't expect. If you enable them, use git status as a checkpoint between agent turns.0.0.x releases have no semver guarantees; a "patch" in a pre-1.0 package can still change tool names or input schemas, which silently changes agent behaviour. Skim the compare diff on each bump.CLAUDE.md/rules file) to filter by prefix or controller rather than dumping everything.How can I help you explore Laravel packages today?