PHPackages                             gardi/mcp-laravel - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. gardi/mcp-laravel

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

gardi/mcp-laravel
=================

An MCP server that lets AI agents inspect a Laravel app — routes, models, schema, and read-only queries — over stdio.

v0.2.0(today)00MITPHPPHP ^8.2CI passing

Since Jun 26Pushed todayCompare

[ Source](https://github.com/NarimanGardi/mcp-laravel)[ Packagist](https://packagist.org/packages/gardi/mcp-laravel)[ RSS](/packages/gardi-mcp-laravel/feed)WikiDiscussions main Synced today

READMEChangelogDependencies (7)Versions (2)Used By (0)

mcp-laravel
===========

[](#mcp-laravel)

[![Tests](https://github.com/NarimanGardi/mcp-laravel/actions/workflows/tests.yml/badge.svg)](https://github.com/NarimanGardi/mcp-laravel/actions/workflows/tests.yml)[![Latest version](https://camo.githubusercontent.com/09b707d3870d0e70a925e5957a907d9c948e34bdb24faa595ce658c647446261/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f67617264692f6d63702d6c61726176656c)](https://packagist.org/packages/gardi/mcp-laravel)[![License](https://camo.githubusercontent.com/5385dd47fc4ab0e9edf4c05d6162b9a10cc47d6d6ba88ae23e1df5fc8f640159/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f67617264692f6d63702d6c61726176656c)](LICENSE)

An MCP server that lets an AI coding agent inspect a Laravel application — its routes, models, database schema, and (optionally) read-only query results — over stdio or HTTP.

I kept watching agents guess at a Laravel codebase: inventing model attributes, half-remembering route names, assuming a column exists. They were working from the training set, not the app in front of them. This exposes the real thing as a handful of tools the agent can call, so it reads your schema instead of hallucinating it.

It's deliberately small. Four tools, no daemon, no extra services — just an artisan command that speaks the Model Context Protocol on stdin/stdout.

Requirements
------------

[](#requirements)

- PHP 8.2+ (8.3+ for Laravel 13)
- Laravel 12 or 13

Install
-------

[](#install)

```
composer require gardi/mcp-laravel --dev
```

The service provider is auto-discovered. Run the installer to publish the config and print the client snippet for you:

```
php artisan mcp:install
```

(Or just `php artisan vendor:publish --tag=mcp-config` if you only want the config.)

Connect an agent
----------------

[](#connect-an-agent)

The server runs over stdio, so any MCP client launches it the same way — point it at this app's directory and have it run `php artisan mcp:serve`. For example, in an MCP client's server config:

```
{
  "mcpServers": {
    "laravel": {
      "command": "php",
      "args": ["artisan", "mcp:serve"],
      "cwd": "/absolute/path/to/your/laravel/app"
    }
  }
}
```

That's it — the agent can now list and call the tools below. Ready-made configs for Claude Code, Cursor, Windsurf and Cline live in [`examples/`](examples/).

See it in action
----------------

[](#see-it-in-action)

A real session (handshake → tool list → a `relationship_graph` call) is captured in [`demo/session.md`](demo/session.md) and reproducible with `./demo/run.sh` — it boots the real server via Testbench, nothing is mocked. An abbreviated peek (the demo uses the package's Post/Comment fixtures; you'd see your app's own models):

```
// initialize → the server announces itself
{ "protocolVersion": "2024-11-05", "serverInfo": { "name": "mcp-laravel", "version": "0.3.0" } }

// relationship_graph → the domain, as a graph the agent can read
{
  "modelCount": 2,
  "edges": [
    { "from": "App\\Models\\Post",    "relation": "comments", "type": "HasMany",   "to": "App\\Models\\Comment" },
    { "from": "App\\Models\\Comment", "relation": "post",     "type": "BelongsTo", "to": "App\\Models\\Post" }
  ]
}
```

Record a GIF of the session with [VHS](https://github.com/charmbracelet/vhs): `vhs demo/demo.tape`.

HTTP transport
--------------

[](#http-transport)

Prefer running it as a service instead of stdio? Enable the HTTP transport and the server is exposed at one bearer-authenticated endpoint:

```
MCP_HTTP_ENABLED=true
MCP_HTTP_TOKEN=a-long-random-secret
# MCP_HTTP_PATH=mcp   # default
```

Then point an HTTP-capable MCP client at `POST https://your-app.test/mcp` with an `Authorization: Bearer ` header. It's **off by default and won't register without a token** — never expose your schema unauthenticated. Both transports run the same protocol handler (a transport-agnostic `Dispatcher`).

Tools
-----

[](#tools)

ToolWhat it returns`list_routes`Methods, URI, name, action and middleware (optional substring filter).`list_models`Eloquent models found under `app/Models`, with their tables.`describe_model`A model's table, columns, fillable/hidden, casts and relationships.`relationship_graph`Every model and its relationships as a graph (nodes + edges).`describe_table`Any table's columns, indexes and foreign keys (not just models).`database_schema`Every table with its columns — a whole-schema overview.`explain_query`The query plan (EXPLAIN) for a read-only SELECT — without running it.`tail_logs`The last lines of a log file (newest in `storage/logs` by default).`config_get`Configuration values, with sensitive ones redacted.`migration_status`Which migrations have run vs. are pending, with batch numbers.`list_commands`Registered Artisan commands with descriptions.`model_query`Rows from a read-only Eloquent query (filters, columns, relations). Opt-in.`database_query`Rows from a single **read-only** SELECT. Opt-in (see below).A note on the data tools
------------------------

[](#a-note-on-the-data-tools)

`model_query` and `database_query` both return row data, so both are **off by default** — enable them with `MCP_MODEL_QUERY=true` / `MCP_DATABASE_QUERY=true`. `model_query` can't run raw SQL (it builds an Eloquent query from structured arguments), which makes it the safer of the two.

For `database_query` specifically: when enabled, every query is validated as a single read-only statement *and* run inside a transaction that is always rolled back. That's defense in depth, not a guarantee — the right way to run it is against a least-privilege, read-only database user. Enable it with:

```
MCP_DATABASE_QUERY=true
MCP_DB_CONNECTION=readonly   # optional: a read-only connection
```

Resources
---------

[](#resources)

Beyond tools, the server exposes read-only **resources** — context a client can attach to a conversation rather than call on demand:

URIContent`laravel://schema`The whole database schema (tables + columns).`laravel://routes`Every route (method, URI, name, action, middleware).`laravel://models`The model relationship graph.They're served via `resources/list` / `resources/read` and are thin adapters over the tools of the same name. Toggle them in the `resources` config block.

Prompts
-------

[](#prompts)

The server also ships **prompts** (`prompts/list` / `prompts/get`) — parameterised templates a client can surface as slash commands. Each points the agent at the tools above, so a one-click prompt turns into grounded work:

PromptDoes`explain_app`Tours the app via its routes, model graph and schema.`review_model`Reviews a model (arg: `model`) — relations, casts, N+1, mass-assignment.`write_test`Writes a Pest test (arg: `subject`), inspecting routes/models first.`debug_recent_error`Reads recent logs with `tail_logs` and traces the latest error.Toggle them in the `prompts` config block.

Limitations
-----------

[](#limitations)

Worth knowing before you rely on it:

- `list_models` / `relationship_graph` assume the Laravel default PSR-4 mapping (`App\Models` → `app/Models`). For models elsewhere, set `models_path` / `models_namespace` in the config (or the `MCP_MODELS_PATH` / `MCP_MODELS_NAMESPACE`env vars).
- `describe_model` detects relationships only when the relation method declares a return type (e.g. `public function posts(): HasMany`). Untyped relation methods aren't listed — calling every method to find out would be unsafe.
- The `database_query` / `explain_query` read-only check is a keyword/structure heuristic, not a SQL parser. Pair it with a read-only DB user; don't treat the heuristic as your only line of defense.
- `tail_logs` returns whatever is in your log files, which can include sensitive data (exception payloads, tokens). Disable it or scrub logs if that matters.

Development
-----------

[](#development)

```
composer install
./vendor/bin/pest
```

License
-------

[](#license)

MIT — see [LICENSE](LICENSE).

###  Health Score

36

—

LowBetter than 79% of packages

Maintenance100

Actively maintained with recent releases

Popularity0

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity35

Early-stage or recently created project

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

0d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/110671428?v=4)[Nariman Gardi](/maintainers/NarimanGardi)[@NarimanGardi](https://github.com/NarimanGardi)

---

Top Contributors

[![narimanmuhsin](https://avatars.githubusercontent.com/u/130443709?v=4)](https://github.com/narimanmuhsin "narimanmuhsin (56 commits)")

---

Tags

aiai-agentslaravelmcpmodel-context-protocolphplaravelmcpaiagentsModel Context Protocol

###  Code Quality

TestsPest

### Embed Badge

![Health badge](/badges/gardi-mcp-laravel/health.svg)

```
[![Health](https://phpackages.com/badges/gardi-mcp-laravel/health.svg)](https://phpackages.com/packages/gardi-mcp-laravel)
```

###  Alternatives

[psalm/plugin-laravel

Psalm plugin for Laravel

3345.1M337](/packages/psalm-plugin-laravel)[laravel/ai

The official AI SDK for Laravel.

9782.1M162](/packages/laravel-ai)[laravel/mcp

Rapidly build MCP servers for your Laravel applications.

76518.2M120](/packages/laravel-mcp)[spatie/laravel-health

Monitor the health of a Laravel application

87411.3M153](/packages/spatie-laravel-health)[aedart/athenaeum

Athenaeum is a mono repository; a collection of various PHP packages

245.2k](/packages/aedart-athenaeum)[laravel/surveyor

Static analysis tool for Laravel applications.

8690.3k12](/packages/laravel-surveyor)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
