Продвинутый · По стеку

Laravel через Claude Code

Как выстроить продуктивную и предсказуемую работу над Laravel-проектом: правильные MCP-серверы, чёткие правила в CLAUDE.md и рабочий цикл, при котором Claude пишет код в вашей архитектуре, а не в своей.

laravel-boost MCP CLAUDE.md правила TDD-цикл

Главная идея

Claude пишет в вашей архитектуре, а не в своей
Laravel — фреймворк с сильными соглашениями. Без правил Claude свалит логику в контроллер, использует $request->all() и проигнорирует ваш слой сервисов. Связка MCP + CLAUDE.md даёт ему карту проекта и жёсткие рамки — и код выходит таким, будто его писал ваш сеньор.

Три опоры продуктивной работы: 1) MCP, чтобы Claude видел реальную структуру приложения, а не угадывал по файлам; 2) CLAUDE.md и MD-файлы, чтобы он знал ваши правила; 3) рабочий цикл через тесты и Plan Mode, чтобы изменения были управляемыми.

MCP-серверы для Laravel-проекта

Правильный набор MCP экономит десятки тысяч токенов: вместо чтения сотен PHP-файлов Claude получает структурированные данные одним вызовом.

laravel-boost
главный для Laravel
Запускается внутри контейнера и отдаёт роуты, модели, события, конфиг и Artisan напрямую. Claude видит приложение «изнутри», а не по исходникам.
context7
документация
Подгружает актуальную документацию Laravel, Filament, Livewire прямо в контекст. Спасает от устаревших ответов модели по старым версиям API.
postgres-mcp
только чтение
Read-only доступ к БД для анализа схемы, медленных запросов и данных Telescope. Запись и миграции остаются за вами — см. Базы данных.
docker
запуск команд
Выполняет тесты, Artisan и Composer внутри контейнера, где живёт приложение. Без него Claude работает «вслепую» относительно реального окружения.
Почему именно так: laravel-boost даёт «карту» приложения, context7 — свежую документацию, postgres-mcp — реальные данные, docker — руки для запуска. Вместе они закрывают то, что Claude иначе угадывал бы по файлам.

Что Claude умеет через laravel-boost

laravel-boost запускается внутри Laravel-контейнера и даёт Claude прямой доступ к роутам, моделям, событиям, конфигурации и Artisan — без чтения файлов вручную.

Видит все роуты
Метод, URI, контроллер, middleware — без чтения route-файлов
Структуру моделей
fillable, casts, связи Eloquent одним запросом
Безопасный Artisan
route:list, model:show, очереди — без риска для данных
Статус очередей
Horizon, джобы, зависшие задачи — для отладки
Данные Telescope
Медленные запросы, исключения, N+1 проблемы
События и конфиг
Листенеры, настройки (без секретов) в структурном виде

Подключение: .mcp.json

// .mcp.json для Laravel-проекта: { "mcpServers": { "laravel-boost": { "command": "docker", "args": [ "exec", "-i", "phone-rosveb-ru-backend-1", // имя контейнера Laravel "php", "artisan", "boost:mcp" ] } } }

Инструменты laravel-boost

ИнструментЧто делает
boost_routesСписок всех роутов с методом, URI, контроллером, middleware
boost_modelsСтруктура Eloquent-моделей: fillable, casts, relations
boost_eventsСобытия и листенеры
boost_configКонфигурация (без secrets)
boost_artisanЗапуск безопасных Artisan-команд
boost_queueСтатус очередей и джобов
Экономия контекста: вместо чтения 50+ PHP файлов Claude получает структурированные данные через один вызов. Это экономит тысячи токенов на каждый запрос.

CLAUDE.md и MD-файлы: правила проекта

MD-файлы — это «мозг» проекта для Claude. Они попадают в контекст автоматически и задают правила, которым он следует в каждой сессии. Для Laravel чёткий CLAUDE.md важнее любого промпта.

CLAUDE.md (корень проекта)
Стек и версии (Laravel 11, PHP 8.3, PostgreSQL), архитектурные правила (логика в Service, не в Controller), запреты ($request->all(), Eloquent в контроллере, migrate:fresh), стандарт кода (final, readonly, strict types), как запускать тесты.
CLAUDE.md (вложенные)
В крупных модулях (например app/Domain/Billing/) — свой CLAUDE.md с локальными правилами. Claude читает ближайший к редактируемому файлу. Подробнее — Иерархия конфигов.
docs/adr/*.md — архитектурные решения
Записи «почему сделали так»: выбор пакета, паттерн оплаты, отказ от Repository. Claude не предложит переписать то, что уже взвешенно решено.
docs/specs/*.md — спецификации фич
Перед крупной задачей — MD-спека: что строим, какие эндпоинты, какие правила валидации. Claude реализует по ней, а не по догадкам.
Правило хорошего CLAUDE.md: конкретика вместо общих слов. Не «пиши чистый код», а «бизнес-логика только в app/Services, контроллер вызывает сервис и возвращает Resource». Чем конкретнее правило — тем точнее результат.

Оптимальный рабочий цикл

Самый надёжный режим для Laravel — разработка через тесты (TDD на Pest) под контролем Plan Mode. Claude движется маленькими проверяемыми шагами:

1
Спецификация и план
Опишите задачу (или дайте MD-спеку), включите Plan Mode. Claude составляет план изменений — вы утверждаете до того, как он тронет код.
2
Сначала тест (red)
Claude пишет Pest Feature-тест на новое поведение. Тест падает — это нормально, поведения ещё нет. Тест фиксирует, что именно мы строим.
3
Реализация (green)
FormRequest для валидации → Service для логики → Controller как тонкий HTTP-слой → Resource на выход. Claude пишет минимум, чтобы тест прошёл.
4
Прогон тестов в контейнере
Через docker-MCP Claude запускает Pest на реальном окружении. Гоняйте только затронутые тесты — быстрее обратная связь.
5
Рефактор и форматирование
Pint приводит код к стандарту, Claude чистит дубли. Тесты остаются зелёными — рефакторинг безопасен.
6
Ревью диффа и коммит
Прочитайте git diff перед коммитом. Миграции запускаете и проверяете вы — это зона человека, а не агента.

Архитектура, которую держит Claude

Пропишите этот поток данных в CLAUDE.md — и Claude перестанет складывать всё в контроллер. Каждый слой отвечает за своё:

HTTP IN
FormRequest
Валидация входа. Только validated(), никогда all().
КОНТРОЛЛЕР
Controller
Тонкий HTTP-слой. Вызывает сервис, возвращает Resource.
ЛОГИКА
Service
Вся бизнес-логика. Транзакции, события, оркестрация.
ДАННЫЕ
Model / Repository
Eloquent и доступ к БД. Изолирован от контроллера.

Controller — только HTTP-слой

<?php declare(strict_types=1); namespace App\Http\Controllers\Api; use App\Http\Requests\StorePaymentRequest; use App\Http\Resources\PaymentResource; use App\Services\PaymentService; final class PaymentController { // DI через конструктор — тестируемость public function __construct( private readonly PaymentService $paymentService ) {} public function store(StorePaymentRequest $request): PaymentResource { // Валидация — в FormRequest, логика — в Service $payment = $this->paymentService->create($request->validated()); return new PaymentResource($payment); } }

Service — бизнес-логика

<?php declare(strict_types=1); namespace App\Services; use App\Models\Payment; use Illuminate\Support\Facades\DB; final class PaymentService { public function __construct( private readonly PaymentRepository $repository, private readonly NotificationService $notifications ) {} public function create(array $data): Payment { return DB::transaction(function () use ($data) { $payment = $this->repository->create($data); $this->notifications->paymentCreated($payment); return $payment; }); } }

Pest TDD — тесты как первый класс

Структура Feature-теста

<?php // tests/Feature/PaymentTest.php uses(Tests\TestCase::class, Illuminate\Foundation\Testing\RefreshDatabase::class); describe('Payment creation', function () { it('creates payment for authenticated user', function () { // Arrange $user = User::factory()->create(); $payload = ['amount' => 1000, 'currency' => 'RUB']; // Act $response = $this ->actingAs($user) ->postJson('/api/v1/payments', $payload); // Assert $response->assertCreated() ->assertJsonStructure(['data' => ['id', 'amount', 'status']]); $this->assertDatabaseHas('payments', [ 'user_id' => $user->id, 'amount' => 1000, ]); }); it('requires authentication', function () { $this->postJson('/api/v1/payments', [])->assertUnauthorized(); }); });

Запуск тестов

// Через Docker MCP: mcp__docker__docker_exec({ container: "phone-rosveb-ru-backend-1", command: "./vendor/bin/pest --parallel" }) // Только изменённые тесты: mcp__docker__docker_exec({ container: "phone-rosveb-ru-backend-1", command: "./vendor/bin/pest tests/Feature/PaymentTest.php" })

Artisan — полезные команды

КомандаКогда использоватьБезопасно?
php artisan route:listПросмотр роутов
php artisan model:show UserСтруктура модели
php artisan queue:work --onceОбработать 1 джоб
php artisan cache:clearОчистить кэш
php artisan telescope:clearОчистить Telescope логи
php artisan migrateНакатить миграции⚠️ Проверить!
php artisan migrate:statusСтатус миграций
php artisan migrate:fresh🚫 УДАЛИТ ВСЕ ДАННЫЕ❌ Заблокировано
php artisan db:wipe🚫 УНИЧТОЖИТ БД❌ Заблокировано
⚠️
Частая ошибка новичков: Claude Code может попытаться выполнить php artisan migrate:fresh в процессе отладки или настройки — особенно если вы попросили «создать чистую БД». Эта команда удаляет все таблицы и все данные без предупреждения. Заблокируйте её в hooks или deny-списке. Используйте только php artisan migrate в продакшн-подобной среде. В тестовой среде — только с явным подтверждением через Plan Mode.

Telescope & Horizon

Telescope — отладка через MCP

Laravel Telescope записывает все запросы, очередные задачи, исключения, запросы к БД. Claude Code может читать Telescope данные через laravel-boost или запросы к БД.

-- Последние медленные запросы через postgres-mcp: SELECT content->>'slow_query' AS query, content->>'time' AS ms FROM telescope_entries WHERE type = 'query' AND (content->>'time')::float > 100 ORDER BY created_at DESC LIMIT 20;

Horizon — мониторинг очередей

// Просмотр статуса Horizon через laravel-boost: boost_artisan({ command: "horizon:status" }) boost_artisan({ command: "horizon:list" }) // Приостановить обработку для отладки: boost_artisan({ command: "horizon:pause" }) // Возобновить: boost_artisan({ command: "horizon:continue" })

Стандарты кода Laravel

pint.json — форматирование

{ "preset": "psr12", "rules": { "declare_strict_types": true, "single_quote": true, "ordered_imports": { "sort_algorithm": "alpha" }, "no_unused_imports": true, "final_class": true, "trailing_comma_in_multiline": true } }
✅ final class везде
Service, Controller, FormRequest — все final. Наследование запрещено без явного обоснования.
✅ readonly properties
Параметры конструктора помечать readonly. Иммутабельность — главное правило DI.
❌ $request->all()
Запрещено! Использовать $request->validated() только. Иначе mass assignment уязвимость.
❌ Eloquent в Controller
Контроллер не должен знать про Eloquent. Только Service/Repository → Controller.
✅ DB::transaction()
Любая операция с несколькими записями — в транзакции. Автоматический rollback при Exception.
✅ FormRequest + Resource
Входные данные — через FormRequest (валидация). Выходные — через JsonResource (сериализация).

CMS на базе Laravel

Filament (Admin Panel)

// Работа с Filament через Claude: // 1. Читать ресурсы через Serena (LSP понимает PHP) // 2. Artisan для генерации: boost_artisan({ command: "make:filament-resource Payment --generate" }) // 3. Telescope показывает N+1 запросы при загрузке таблиц // 4. Правило: withRelationships() для всех relation columns

Nova / Voyager

// Nova — аналогично Filament. Ресурсы генерируются Artisan: boost_artisan({ command: "nova:resource Payment" }) // Главное правило при работе с CMS: // НЕ модифицировать vendor-пакеты напрямую // Использовать service providers и extension points
💡
CMS + Claude: Context7 MCP автоматически загружает документацию Filament/Nova при запросах. Убедись, что context7 есть в .mcp.json.

Sanctum — API аутентификация

<?php // routes/api.php — правильная структура: Route::middleware('auth:sanctum')->group(function () { Route::apiResource('payments', PaymentController::class); Route::apiResource('subscriptions', SubscriptionController::class); }); // Публичные роуты: Route::post('/auth/login', [AuthController::class, 'login']); Route::post('/auth/register', [AuthController::class, 'register']);
⚠️
Sanctum + Reverse Proxy: при работе за Caddy нужно настроить SANCTUM_STATEFUL_DOMAINS или переключиться на Bearer token аутентификацию для SPA. Без этого CSRF-проверки не пройдут.

Лучшие практики разработки

Делать
  • Бизнес-логику — в Service-классы
  • Валидацию — в FormRequest, выдачу — в Resource
  • final, readonly, strict types по умолчанию
  • Операции с несколькими записями — в транзакции
  • Тесты на Pest до реализации (TDD)
  • Зависимости через конструктор (DI) — тестируемость
Избегать
  • $request->all() — mass assignment
  • Eloquent-запросы прямо в контроллере
  • Бизнес-логика в модели или контроллере
  • Правка vendor-пакетов напрямую
  • N+1 запросы — забытый eager loading
  • migrate:fresh и db:wipe в работе

Типовые ошибки

Частые вопросы

С двух вещей: подключить laravel-boost MCP (чтобы Claude видел структуру) и написать конкретный CLAUDE.md с вашими архитектурными правилами. Это даёт 80% результата. Дальше — context7 для документации и docker-MCP для запуска тестов. Продвинутые приёмы работы с Boost, Skills и Documentation API — на странице Laravel Boost — продвинутые лайфхаки.
Чтение файлов жжёт контекст и неточно: чтобы понять все роуты, Claude прочитает route-файлы, контроллеры и middleware. laravel-boost отдаёт готовую карту приложения одним вызовом — экономия тысяч токенов и меньше ошибок.
Версии стека; правило «логика в Service, контроллер тонкий»; validated() вместо all(); стандарт кода (final, readonly, strict types); как запускать тесты; список запрещённых команд (migrate:fresh, db:wipe). Конкретика важнее объёма.
Генерацию migration-файла — да. Запуск на проде — нет: это зона человека. Claude пишет миграцию, вы её читаете, делаете бэкап и запускаете сами. migrate:fresh и db:wipe блокируются. Подробнее — на странице Базы данных.
Закрепите TDD в CLAUDE.md («сначала Pest-тест, потом реализация») и ведите его по циклу red-green-refactor. В Plan Mode требуйте, чтобы в плане первым шагом был тест. Со временем это становится поведением по умолчанию.
Да. Генерацию ресурсов делайте через Artisan, документацию подгружайте через context7, а N+1 запросы ловите через Telescope. Главное правило — не править vendor-пакеты напрямую, а использовать расширения и провайдеры. Sanctum за Caddy требует SANCTUM_STATEFUL_DOMAINS или Bearer-токенов.