DEV Community

Cover image for I gave my Laravel API generator an MCP server
Loic Aron Mbassi Ewolo
Loic Aron Mbassi Ewolo

Posted on

I gave my Laravel API generator an MCP server

Coding agents write Laravel code well. Ask one for a CRUD API and it will write the model, controller, requests, resource, policy, migration, factory, seeder and tests by hand, slightly differently every time, and you get to review all of it.

I maintain Laravel API Generator, a dev-only package that writes those files from a schema, with tests that pass and code that passes Pint. Version 4.0 gives it an MCP server, so the agent calls the generator instead of typing the files.

Two commands

The server runs on Laravel MCP, which needs Laravel 12.41 or later.

composer require --dev nameless/laravel-api-generator laravel/mcp
claude mcp add -s project laravel-api-generator -- php artisan api-generator:mcp
Enter fullscreen mode Exit fullscreen mode

With -s project, Claude Code writes .mcp.json, which you can commit so the whole team gets the server. Cursor and other clients take the same command, php artisan api-generator:mcp, and in VS Code the extension registers it for Copilot's agent mode on its own.

The agent gets four tools:

Tool What it does
list-entities Returns each generated entity with its files, marked intact, edited or missing
plan-api Lists every file a generation would create or update, with warnings, without writing anything
generate-api Writes the files, from an api-schema document or an OpenAPI spec of the project
add-fields Adds columns to an entity, with an incremental migration and in-place patches

The first two are marked read-only, so your client knows they change nothing. The server also ships a design-api prompt, which Claude Code offers as a slash command, and exposes the JSON Schema of the schema format as a resource.

Plan first

Here is the run from the video: /mcp__laravel-api-generator__design-api with one sentence, a library that lends books to members. The agent checked what already existed, drafted a schema and called plan-api.

Claude Code proposing 4 entities and 56 files before writing anything

Four entities, 56 files, no warnings, and a question at the end: generate it as is, or change something first? After the go, generate-api wrote everything and the 62 generated tests passed.

Your edits stay yours

The package records every file it writes in .api-generator/manifest.json. A file you changed since is reported as edited, and generate-api leaves it as it is ("kept": true in the result). The server never deletes a file and never runs a migration. Overwriting your edits with --force, deleting an entity and migrating stay on the command line.

In the demo, LoanService.php got a hand-written rule. Asked for a notes field on loans, the agent read the manifest, saw the edited service, ran add-fields as a dry run first, and the service came out untouched.

One gap showed up while filming: add-fields doesn't update the DTO yet, so the agent patched LoanDTO.php itself. That's the next fix on my list.

What the generated code looks like in 4.0

4.0 is a major release because the output changed. It needs Laravel 12 or 13, while Laravel 10 and 11 stay on the 3.x line.

Controllers bind the model from the route and start every action with the policy:

public function update(UpdateArticleRequest $request, Article $article)
{
    Gate::authorize('update', $article);

    $dto = ArticleDTO::fromRequest($request);

    return new ArticleResource($this->service->update($article, $dto));
}
Enter fullscreen mode Exit fullscreen mode

The update rules start with sometimes, and the DTO remembers which keys the request sent, so a PATCH with a single field changes that field and nothing else. The index is paginated, filtered and sorted out of the box:

GET /api/articles?filter[status]=published&sort=-created_at&per_page=20
Enter fullscreen mode Exit fullscreen mode

On Laravel 13, models declare their fillable columns with #[Fillable]. Enums are named after the entity and the field (ArticleStatus), and every generated file passes pint --test with the Laravel preset, which the CI checks on both Laravel versions.

The VS Code extension, redesigned

Not everyone drives an agent. The VS Code extension does the same work with a form, and 1.1 redesigns it.

Pick an example, add a relation, and the live preview follows

The preview on the right comes from the package installed in your project, through a long-running php artisan api-generator:serve --stdio, so it shows exactly the files that will be written, diffs included. A database, a schema file, a Mermaid diagram, an OpenAPI spec and a plain description drafted by Copilot all end on the same review screen before anything is written.

The review of an OpenAPI spec, then the generation

After a generation, the panel runs the next steps in place: migrations, tests, seeding and the Scramble docs.

One click on Generate, then the migrations and the tests

It's also on Open VSX for Cursor and VSCodium.

What it doesn't do

It generates code, and that's all. Autocompletion and navigation for Eloquent and Blade are the job of the official Laravel extension. The MCP server needs Laravel 12.41 or later. And the output is opinionated, with a thin controller, a service and a DTO: if your team writes CRUD differently, publish the stubs and change them, and api-generator:validate-stubs checks them.

Links

It's free and MIT. If you try it on a real schema, tell me what breaks, here or in an issue.

Top comments (0)