Manage the lerd local PHP development environment via MCP tools: run framework console commands (artisan, bin/console, etc.), manage services, start/stop queue workers, run composer, manage Node.js…

MITAuto-check: warningsBackend & APIs

Install Lerd

The automated check flagged lines worth reading first. See the safety section below.

skills CLI
$ npx skills add liberusoftware/real-estate-laravel --skill lerd -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install liberusoftware/real-estate-laravel lerd --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/liberusoftware/real-estate-laravel.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.claude/skills/lerd .claude/skills/lerd && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
lerd
GitHub stars
112
Token cost
~7.8k tokens
SKILL.md length
4,150 words
Files
1
Skills in repo
3
Repo updated
First seen
Licence
MIT

At a glance

Manage the lerd local PHP development environment via MCP tools: run framework console commands (artisan, bin/console, etc.), manage services, start/stop queue workers, run composer, manage Node.js…

  • Tasks that involve Backend development
  • Calls npm, composer and pnpm; needs APP_KEY and STRIPE_SECRET
  • Tasks that involve MCP servers
  • Tasks that involve Query optimization

What it does

Lerd is an agent skill from liberusoftware/real-estate-laravel. Manage the lerd local PHP development environment via MCP tools: run framework console commands (artisan, bin/console, etc.), manage services, start/stop queue workers, run composer, manage Node.js versions, and inspect site status. Also the way to diagnose and optimize a slow site: find N+1 and slow queries, read per-site response-time and slow-route timings, profile requests, and run site health checks, from real captured traffic rather than reading code.

Its SKILL.md is about 7.8k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.

It sits in Backend & APIs, covering Backend development, MCP servers and Query optimization. It works with PHP, Laravel, Node.js and npm. The repository describes itself as: Real Estate / Estate Agent, solution for your Property Agency. Application written in Laravel 13 / PHP 8.5 using Filament 5. Support for Rightmove, Zoopla, OnTheMarket. The licence is MIT.

When your agent uses it

  • Tasks that involve Backend development
  • Tasks that involve MCP servers
  • Tasks that involve Query optimization

Example prompts

  • “/lerd”

Requirements

  • Node.js

What it can do on your machine

Read from SKILL.md and the folder at commit 8d7119e. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    Shell commands in SKILL.md call:

    • npm
    • composer
    • pnpm
    • yarn
    • nvm
    • node
    • git

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    No URLs in SKILL.md. Its commands use npm, pnpm, yarn and git, which can reach the network depending on how they are called.

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names these keys or tokens, usually read from environment variables:

    • APP_KEY
    • STRIPE_SECRET
    • STRIPE_SECRET_KEY
    • STRIPE_API_KEY

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Lerd loads about 7.8k tokens when it runs. Until then it costs about 117 tokens; SKILL.md has 4,150 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~117
When it runs · the whole SKILL.md, loaded when a task matches
~7.8k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check: warnings

The automated check found patterns that need a careful read before installing.

  • NoteMentions a .env fileSKILL.md:23
    red sites); `vendor/`, `node_modules/`, `.env` are seeded from the main checkout. `.lerd.yaml` `env_overrides` declares
  • NoteMentions a .env fileSKILL.md:56
    - `env` returns the recommended `.env` connection keys; `expose` publishes an extra `host:container` port
  • NoteMentions a .env fileSKILL.md:65
    ...]` or `all: true`) and repoints each `.env`; source data is left intact
  • NoteMentions a .env fileSKILL.md:70
    #### `env` — .env management
  • NoteMentions a .env fileSKILL.md:73
    - `check` compares `.env` against `.env.example`
  • NoteMentions a .env fileSKILL.md:74
    rride` manages the personal, gitignored `.env.lerd_override` (its `set` KEY=VALUE win over lerd defaults; `LERD_EXTERNAL
  • NoteMentions a .env fileSKILL.md:95
    - Stripe secret is read from `.env` (STRIPE_SECRET / STRIPE_SECRET_KEY / STRIPE_API_KEY); `stripe_config` sets webhook_p
  • WarningMentions a credentials file (SSH keys, cloud or package-manager tokens)SKILL.md:104
    h-agent container and loads the host's `~/.ssh/id_*` (or named keys) so passphrase-protected keys work in the FPM contai
  • NoteMentions a .env fileSKILL.md:147
    touches nginx, domains, certificates or `.env`. This is not the same thing as the `site` tool's `group_*` actions, which
  • NoteMentions a .env fileSKILL.md:159
    `secured`); (3) configure the project's `.env` with service hosts (`lerd-mysql`, etc.) and start needed services via `se

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from liberusoftware/real-estate-laravel at commit 8d7119e, republished under its MIT licence (© liberusoftware). 4,150 words, ~7,826 tokens.

Download SKILL.mdSave it as .claude/skills/lerd/SKILL.md (or your agent's skills folder).
name
lerd
description
Manage the lerd local PHP development environment via MCP tools: run framework console commands (artisan, bin/console, etc.), manage services, start/stop queue workers, run composer, manage Node.js versions, and inspect site status. Also the way to diagnose and optimize a slow site: find N+1 and slow queries, read per-site response-time and slow-route timings, profile requests, and run site health checks, from real captured traffic rather than reading code.

Lerd, a local PHP development environment

This project runs on lerd, a Podman-based PHP development environment. It is framework-agnostic: Laravel, Symfony, WordPress, Drupal, Magento, CakePHP and any custom framework are all driven by a framework definition (YAML), never by lerd hardcoding a framework's name. The lerd MCP server is available — use it to manage the environment without leaving the chat.

The MCP surface is twelve grouped tools, each driven by an action argument: site, service, db, env, runtime, worker, exec, framework, diag, logs, worktree, workspace. Always pass action. Most actions also accept an optional path that defaults to the directory the assistant was opened in (then LERD_SITE_PATH if set), so you can usually omit it. Start by calling site with action: "list" to discover sites.

Architecture
  • PHP runs in Podman containers named lerd-php<version>-fpm (e.g. lerd-php84-fpm); each container includes composer and node/npm; the PHP version is resolved from .lerd.yaml → .php-version → composer.json require.php constraint (matched against installed versions) → global default
  • Nginx routes *.test domains to the correct PHP-FPM container
  • Services (MySQL, Redis, PostgreSQL, etc.) and custom services run as Podman containers via systemd quadlets
  • Node.js versions run through a version manager, fnm (bundled, fetched on demand) or user nvm (declining managed Node picks nvm; node.manager + node.nvm_dir; node:manager/dashboard; nvm keeps PATH, fnm uses shims); per-project version via a .node-version file. The package manager is the project's, not lerd's: a packageManager pin in package.json wins, then the lockfile (pnpm-lock.yaml → pnpm, yarn.lock → yarn, bun.lock* → bun, else npm). pnpm and yarn run through corepack, and installs use the manager's frozen-lockfile mode (pnpm install --frozen-lockfile, yarn install --immutable, npm ci). Never assume npm run dev/npm ci — the worker command and the setup steps follow the detected manager
  • Framework workers (queue, schedule, reverb, horizon, messenger, vite, etc.) run as systemd user services named lerd-<worker>-<sitename>; commands are defined per-framework in YAML; Laravel Horizon is auto-detected from composer.json and replaces the queue toggle when installed; Laravel ships with a vite host worker that runs the project's dev script on the host for HMR, through whichever package manager the project pins; workers and setup commands support optional check (file or composer) for conditional visibility; workers with conflicts_with auto-stop conflicting workers on start. Per-worker flags: host: true (run on host via the version manager instead of in FPM container — HMR-sensitive Node tools), per_worktree: true (worker runs independently per worktree under lerd-<worker>-<site>-<branch>), replaces_build: true (worker provides asset manifest while running, so a worktree add skips the static npm run build step when this worker is opted in)
  • Custom workers can be added per-project (.lerd.yaml custom_workers) or globally (~/.config/lerd/frameworks/<name>.yaml); use the worker tool's add/remove actions — both survive framework store updates
  • Framework setup commands (one-off bootstrap steps like migrations, storage links) are defined in the framework YAML and shown by framework action: "setup"; Laravel has built-in storage:link/migrate/db:seed; custom frameworks can define their own
  • Service version placeholders ({{mysql_version}}, {{postgres_version}}, {{redis_version}}, {{meilisearch_version}}) are available in framework env vars and resolved from the service image tag at env-setup time
  • Custom containers: non-PHP sites (Node.js, Python, Go, etc.) can define a Containerfile.lerd and a container: section in .lerd.yaml with a port; lerd builds a per-project image, runs it as lerd-custom-<sitename>, and nginx reverse-proxies to it; the project directory is volume-mounted at its host path with --workdir set automatically — do NOT add WORKDIR or COPY to the Containerfile; workers exec into the custom container; services are accessible by name on the shared lerd Podman network; hot-reload file watchers must use polling on macOS (inotify does not fire across Podman Machine's virtiofs mount) — nodemon: --legacy-watch, Vite: server.watch.usePolling: true, webpack: watchOptions: { poll: 1000 }
  • Custom-image PHP sites (custom-FPM): a PHP project can define a Containerfile.lerd (must build FROM lerd-php<ver>-fpm:local) plus a container: section with no port; lerd builds a per-site image (lerd-custom-<site>:local), runs a dedicated FPM container lerd-cfpm-<site>, and serves it by fastcgi instead of the shared lerd-php<ver>-fpm. It is a normal PHP site otherwise (xdebug, dumps, profiler, lerd shell, php/artisan/composer/tinker, queue/horizon all run in the per-site container). The PHP version is fixed by the FROM line (the UI version selector is read-only); lerd rebuild rebuilds the image. Same key as custom containers, the port is the discriminator: with a port it is a reverse-proxied non-PHP app, without a port it is a fastcgi PHP image. runtime for these reports fpm-custom.
  • Git worktrees automatically get a <branch>.<site>.test subdomain (deep *.<branch>.<site>.test wildcard cert + nginx server_name on secured sites); vendor/, node_modules/, .env are seeded from the main checkout. .lerd.yaml env_overrides declares templated env vars ({{domain}}, {{scheme}}, {{site}}) layered on the default APP_URL rewrite — for multi-tenant apps (per-branch cookies, signed-URL hosts, tenant routing)
DNS modes

Lerd has two install-time DNS modes recorded in ~/.config/lerd/config.yaml:

  • Managed (default): dns.enabled: true, dns.tld: test. Sites at *.test via lerd-dns + mkcert; site tls_enable works.
  • Disabled: dns.enabled: false, dns.tld: localhost. Sites at *.localhost via RFC 6761; no mkcert CA, TLS toggling unavailable.

Read diag action: "status" for dns.tld and dns.enabled instead of assuming .test; do not propose tls_enable when dns.enabled is false.

MCP tools

Twelve grouped tools, each selecting behaviour via action.

site — sites and their configuration

Actions: list (discover sites — CALL FIRST), link, unlink, domain_add, domain_remove, group_assign, group_unassign, group_label, group_db, group_list, tls_enable, tls_disable, tls_renew, php, node, pause, unpause, restart, rebuild, runtime, nginx_read, nginx_write, nginx_reset, park, unpark.

  • link registers a directory; non-PHP sites need .lerd.yaml container.port + a Containerfile first, or they register as PHP (wrong)
  • link runs lerd link and returns its output verbatim, so read the reply. It will NOT start a proxy.command dev server (command not approved); ask the user to run lerd link --yes
  • domain_* take a domain without the .test TLD; you can't remove the last domain
  • group_* nest a secondary site under a main's subdomain (one level deep): they identify the secondary by path (defaults to cwd), not by site; group_assign with main + label (+ optional share_db), group_db = share|separate
  • a group secondary follows its main's HTTPS: group_assign under a secured main secures the secondary, tls_enable on a main secures its secondaries too, and tls_disable on a secondary is refused while its main is secured (the main's *.<main> wildcard would answer the subdomain and serve the main's app). Disable the main's TLS first
  • certificates renew themselves before they expire; tls_renew forces it by hand for one site
  • php/node take version; pass branch to pin the override on a worktree's checkout
  • runtime switches fpm ↔ frankenphp (worker: true enables frankenphp worker mode)
  • nginx_write saves a custom override (runs nginx -t, backs up, reloads); branch targets a worktree
  • park registers a parent dir and auto-registers every PHP project under it; unpark reverses it (project files kept)
service — built-in & custom services

Actions: start, stop, restart, pin, unpin, update, rollback, migrate, remove, reinstall, add, expose, port, env, config_read, config_write, config_restore, config_reset, config_list_backups, preset_list, preset_search, preset_install, check_updates, entities, entity_action.

  • update pulls a newer image (safe, in-strategy); migrate dumps + restores across a cross-strategy upgrade; reinstall with reset_data: true wipes data and reprovisions; remove with remove_data: true renames the data dir aside
  • stop marks the service paused — lerd start skips it until started again; pin keeps it always running
  • add registers a custom OCI service (depends_on wires dependencies, init: true for mysql/mariadb); prefer preset_install for anything in preset_list (phpmyadmin, pgadmin, mongo, mongo-express, selenium, stripe-mock, mysql, mariadb…)
  • preset_list returns the installable presets with the metadata each one declares: category (the discovery heading), icon, and admin_for — the services this preset's admin UI administers, which is not depends_on. phpMyAdmin depends on mysql but administers mariadb too, and RedisInsight administers valkey without depending on it. To answer "which dashboard administers this database", read admin_for, not depends_on. preset_search queries the store by name for presets that are not bundled locally
  • env returns the recommended .env connection keys; expose publishes an extra host:container port
  • port moves the service's primary published host port (published_port, or reset: true for the default); it stays bound to 127.0.0.1, the container-internal port is unchanged, and a host-proxy site that points at the old port is realigned automatically
  • entities lists what a service holds that is not a database: the kinds its preset declares (RustFS buckets today, more later), each kind's rows and the actions it supports. Databases have their own tool, so they are not repeated here. entity_action runs one of those declared actions (kind, entity, entity_action); export and import stream a file and stay on the CLI and the dashboard
  • config_* read/write/restore/reset a service's runtime tuning override
db — databases

Actions: list, set, move, create, export, import, snapshot, snapshots, restore, snapshot_delete, extension_list, extension_add.

  • list reports an engine's databases with sizes; service picks the engine, else it resolves from the project. No introspect command, nothing to report
  • set picks the project DB (database: sqlite, mysql, postgres, or a family alternate like mariadb / postgres-pgvector / postgres-timescaledb / mysql-5-7); persists to .lerd.yaml, rewrites DB_ keys, starts the service, creates the DB + _testing
  • move migrates sites between two installed same-family services (from/to, sites: [...] or all: true) and repoints each .env; source data is left intact
  • create/export/import auto-detect service and database; pass service to override. import drops a hosted provider's ownership/DEFINER statements (which can never apply here) and creates any extension the dump's types need; pass fresh: true to empty the database first so a dump replaces what is there instead of colliding with it. What an engine can list and act on is declared in its preset, so this is not a mysql/postgres-only set
  • extension_list/extension_add are postgres-only. An import already creates whatever extension the dump's types reach for, so use these to see what the engine offers and what the database has, or to add one (extension: postgis) before any dump arrives
  • snapshot/snapshots/restore/snapshot_delete are named, restorable snapshots (MySQL/MariaDB/PostgreSQL); restore is destructive; all_databases covers the whole service
env — .env management

Actions: setup, check, override.

  • setup configures services, DBs, APP_KEY and APP_URL; on a fresh Laravel clone call db set first to move off sqlite, then env setup, then ALWAYS framework setup or migrations never run
  • check compares .env against .env.example
  • override manages the personal, gitignored .env.lerd_override (its set KEY=VALUE win over lerd defaults; LERD_EXTERNAL_SERVICES=<svc,svc> marks vars lerd writes but won't start)
runtime — PHP/Node versions & extensions

Actions: versions, node_install, node_uninstall, node_manager, php_list, ext_list, ext_add, ext_remove, ports_list, ports_add, ports_remove, ini_read, ini_write, ini_reset.

  • ext_add/ext_remove change one declared set applying to EVERY PHP version, so a site keeps its extensions across a version change. They rebuild one version's FPM container now (slow); others rebuild on next use. ext_add accepts apk_deps for extra Alpine build packages
  • ext_list reports the declared set plus, per version: has it, predates the set (rebuild fixes), or cannot load it (rebuild won't). Never assume a declared ext is present: mongodb needs 8.1+, 7.4/8.0 are Alpine 3.16
  • node_manager with no argument reports the version manager lerd drives, whether nvm is present and whether lerd manages Node at all; with manager: fnm|nvm it switches, which also rewrites the PATH shims and regenerates host workers
  • php_list sets base_update when the published base image a version was built from has been republished (an upstream PHP or Alpine fix); lerd php:rebuild <version> picks it up
  • ports_add/ports_remove/ports_list publish extra host ports on a PHP version's shell (FPM) container so a process started in lerd shell is reachable at localhost:PORT. ports_add takes host and optional container (defaults to host); a busy host port shifts to the next free one. Per version and independent, loopback-bound (follows lan:expose), restarts that version's FPM. Prefer host-proxy or a worker+proxy for a single site. CLI: lerd php:ports add/remove/list [--php version]
  • ini_read/ini_write/ini_reset edit php.ini: pass version for a per-version file, or shared: true for the shared file applied to every version. The shared file loads below the per-version one, so a per-version key still wins and an unknown key on some version is ignored (not fatal). Prefer shared for a setting you want everywhere, so a version change never drops it. ini_write takes full content, backs up, and restarts the affected FPM containers. CLI: lerd php:ini [version|shared]
  • extra Alpine packages: lerd php:pkg add/remove/list <packages> (CLI) bakes runtime apk packages (CLI tools, libs) into every FPM image, saved in config under php.packages and re-applied on every rebuild, so they survive php:rebuild and base image updates. One declared set applies to every PHP version. Layered onto the shared image, not the published base.
  • Pest browser testing (CLI-only): lerd pest:browser install|doctor|remove [version] sets up pestphp/pest-plugin-browser inside the FPM container by baking Alpine's musl chromium into the images. Chromium only, and current PHP versions only (the 7.4/8.0 legacy tier is rejected). Needs the playwright npm package first; re-run install after bumping it. Tests then run through the normal lerd test/lerd pest.
  • bun: lerd never installs or version-manages bun. On the host, JS install/dev/build run through bun when the project is a bun project (bun.lockb/bun.lock/bunfig.toml/packageManager: bun) or when Node is unmanaged, no system Node exists, and bun is present. CLI-only: lerd node:manage/node:unmanage opt in or out of lerd-managed Node (unmanage drops fnm versions, never a user's nvm ones), lerd js:runtime [bun|node|auto] pins one site's runtime, and lerd php:bun install|update|version manages an in-container bun for lerd shell. These are host operations, not container exec actions.
worker — background workers

Actions: list (CALL FIRST), start, stop, add, remove, health, heal, mode_get, mode_set, and the framework workers queue_start, queue_stop, horizon_start, horizon_stop, reverb_start, reverb_stop, schedule_start, schedule_stop, stripe_start, stripe_stop, stripe_config.

  • call list to discover a site's workers before start; pass branch to target a per-worktree unit
  • use horizon_* instead of queue_* when laravel/horizon is installed (mutually exclusive); queue_start needs Redis running when QUEUE_CONNECTION=redis
  • add saves a custom worker to .lerd.yaml (or the user overlay with global: true); does not auto-start
  • health reports unhealthy units (read-only); heal resets and restarts them (unit for one, omit for all); mode_get reports the macOS worker runtime, mode_set switches it (mode: exec|container)
  • a worker's health state is one of failed (the unit died), expected-but-stopped (it should be running and isn't), or unreachable — the unit is happily active but the server it publishes no longer accepts connections, a dev server that wedged without exiting. All three are heal-able; heal restarts the unit. Per-worktree units (lerd-<worker>-<site>-<branch>) are covered by the same pass, so a dead per-worktree Vite heals like any other. A worker with a schedule is a oneshot driven by a timer and is idle between ticks by design, which is healthy
  • Stripe secret is read from .env (STRIPE_SECRET / STRIPE_SECRET_KEY / STRIPE_API_KEY); stripe_config sets webhook_path / secret_env_key in .lerd.yaml
  • Auto-reload (CLI-only): lerd horizon:reload [on|off] and lerd octane:reload [on|off] (FrankenPHP worker mode) restart workers on file changes; both need the project's chokidar npm package
  • Idle-suspend (CLI-only): lerd idle on/off toggles activity-driven suspension globally; suspended workers stop after the idle timeout (lerd idle timeout <dur>) and resume on the next request/CLI/MCP/file-save. lerd idle pin/unpin <site> exempts a site; lerd idle status reports policy and last-active. A worker shown as suspended is healthy, not failed, so do not heal it
Show full SKILL.md (1,710 more words)Show less
exec — run tooling in the PHP-FPM container

Actions: artisan (Laravel), console (other frameworks), composer, vendor_bins, vendor_run, commands_list, commands_run, command_add, command_remove.

  • artisan/console/composer take args (array); tinker must use --execute=<code> for non-interactive use
  • vendor_run is the right way to run project tooling (pest, phpunit, pint, phpstan, rector) — call vendor_bins first to discover what's installed, then vendor_run with bin + args; prefer it over composer exec
  • commands_*/command_* list, run, add and remove the on-demand commands in a site's .lerd.yaml commands: block; commands_run needs force: true for confirm-gated commands
  • composer over git SSH (CLI-only): when composer needs a private repo reachable only over SSH, lerd auth ssh starts a shared ssh-agent container and loads the host's ~/.ssh/id_* (or named keys) so passphrase-protected keys work in the FPM container; lerd auth ssh --list shows loaded keys, --remove flushes them. Keys live only in agent memory and clear on machine restart
framework — framework definitions & scaffolding

Actions: list, add, remove, prune, search, update, project_new, setup.

  • add with name: "laravel" merges custom workers/setup into the built-in framework
  • remove refuses to drop a definition a linked site still uses (pass force: true to override); prune removes every framework definition no site uses
  • search/update use the community store; definitions auto-fetch on link, so update is the manual refresh (no name refreshes the catalogue and all installed definitions; with name it fetches that one, auto-detecting version from composer.lock)
  • project_new scaffolds a new project (requires absolute path, default framework laravel); follow with site link + env setup
  • setup runs the framework's post-install steps (migrations, storage:link…) — MANDATORY after env setup on new/cloned projects; idempotent
diag — diagnostics & observability

Actions: status, doctor, doctor_fix, site_doctor, which, check, dns_diagnose, bug_report, analyze_queries, route_timing, optimize_route, dumps_recent, dumps_status, dumps_clear, dumps_toggle, profiler_toggle, profiler_status, profiler_clear, profiler_report, xdebug_on, xdebug_off, xdebug_status.

  • status (DNS/nginx/FPM/watcher/tools health) and doctor (JSON findings, each tagged with a fix tier) are the first stops when something is broken; dns_diagnose walks the DNS chain
  • doctor_fix applies the safe (non-heavy, non-sudo) automatic repairs for environment findings; package installs, lerd install, and lerd cleanup stay manual
  • site_doctor runs framework-agnostic app-level checks for one site (env file, env drift, app key, composer/node dependency install + lock, composer audit/npm audit, PHP range, a slow_routes warning for routes whose p95 runs well above the site's typical time or over a second, plus the framework's own checks); pass site (name or domain) or path, defaults to cwd. A failing check carries a severity and, when one applies, a fix naming the command that resolves it — run that yourself (exec, or the named lerd command); site_doctor itself is read-only. slow_routes is the exception: it reads the watcher's request-timing snapshot and has no command fix, the remedy is to profile the route (profiler_toggle)
  • reading logs lives in the logs tool (below), not here
  • which shows resolved PHP/Node/docroot/nginx for a site; check validates .lerd.yaml
  • debug bridge loop: dumps_toggle (enable) → dumps_clear → hit the page → analyze_queries (N+1 / slow-query report with file:line) or dumps_recent (filter by site/branch/ctx/kind/since/limit)
  • route_timing returns the per-site response-time table: the typical (median) time and the routes whose p95 runs well above it (method, example path, p95, multiplier, samples), read from the watcher's request-timing snapshot. Works from recorded traffic alone, no capture needed. site accepts either the site name or its domain, as do analyze_queries, optimize_route, and dumps_recent
  • optimize_route is the join: each slow route paired with the N+1 and slow-query findings captured against that same route (with the caller file:line), so you get the symptom and its cause in one call. Needs the query capture on (dumps_toggle enable) plus a few real hits. When the SPX profiler was on for the route's traffic, each slow route also carries a profile block, the top functions by exclusive wall time from the freshest capture, distilled to a few outliers (not the raw trace), so a CPU-bound route shows where its time went next to its queries
  • optimizing a slow site: don't read controllers to guess at N+1s, drive it from real traffic. route_timing to see which routes are slow → dumps_toggle (enable) and profiler_toggle (enable) → hit the slow route a few times → optimize_route to get its N+1/slow queries with file:line and, from the profiler, the top CPU functions behind it → fix the caller (eager-load, index, cache) or the hot function
  • stay ahead of regressions: when you change request handling or database code on a PHP site, verify you did not introduce a slowdown before moving on, enable dumps, hit the affected route, run optimize_route, and treat a new N+1 or a slow_routes doctor warning as work to finish rather than noise. On an unfamiliar site, route_timing shows the slow routes worth attention first. The timing panel is a live signal (recent traffic only, in memory), so a route you fixed clears once it stops being slow, but the durable catch is the slow_route push notification that fires the moment a route crosses into slow. Periodic checking belongs to the user's own scheduler (a routine, a cron job), not to lerd.
  • profiler_* toggle the global SPX profiler and surface the flame-graph UI; profiler_report (site + args, e.g. ["artisan","app:heavy-report"]) runs that command under SPX and returns a text flat profile, the top functions by wall time and call count, the CPU-bound analog of analyze_queries for when a slow route's cost is not in its queries (a reproducible CLI command, not a live HTTP request); xdebug_* control Xdebug on port 9003 (mode defaults to debug)
  • bug_report writes an anonymised diagnostic report for a GitHub issue
  • disk cleanup (CLI-only): lerd cleanup reclaims podman disk from orphaned lerd images (--dry-run to preview, --deep for the aggressive tier); a daily safe-tier sweep plus post-rebuild/service-change reaping runs automatically, toggled with lerd cleanup auto on|off|status
logs — read logs from any source, filtered

Actions: sources, fetch. Debug without opening files by hand.

  • sources lists every queryable source for the site plus shared infra: app:<file> (framework log files), fpm, worker:<name> (queue/horizon/schedule/custom), and the globals nginx, dns, watcher, ui, services, php<ver>. Call it first to learn the names
  • fetch source=<name> reads one source. Filter with grep (regex, falls back to literal substring), since/until (relative like 15m/1h/2h30m, or a timestamp), level (app logs only: error/warning/info/debug), and lines (default 50)
  • streaming is polling: every fetch returns an opaque cursor; call again with since=<cursor> (or cursor=<cursor>) to get only the new lines. The cursor format differs per backend, so treat it as opaque and echo it back
  • entries come back chronological (oldest first). Raw logs with no timestamps ignore since/level and just return the last N; a not-running container returns partial output, not an error
worktree — git worktrees

Actions: list, add, remove, wait, db_isolate, db_share.

  • add installs deps and offers an asset-worker / build-step prompt; secured sites get *.<branch>.<site>.test wildcard cert SANs + nginx server_name automatically. It waits for setup and reports provisioned (false + note means still running, not failed; timeout_seconds default 300)
  • wait is that readiness check alone, for a worktree made with plain git worktree add. Never judge readiness from the tree: node_modules/ exists from the first extracted package and composer fills existing vendor/<org>/ dirs, so both read as finished mid-install, and racing the watcher is how vendor/ ends up with no autoload.php
  • db_isolate gives a worktree its own database (seed via source: empty|main|<branch>); db_share points it back at the main; remove keeps an isolated DB unless keep_db: false
  • a framework definition can declare what its worktrees need (an isolated database, what it is cloned from, console commands to run once it is in place), so add does that work rather than leaving it to be run by hand
  • request timing is recorded per worktree; pass branch to route_timing, optimize_route and dumps_recent to read one branch's traffic
workspace — group sites for display

Actions: list, create, rename, delete, assign, move.

  • a workspace is a display-only bucket of sites, shown in the dashboard sidebar and the TUI. It never touches nginx, domains, certificates or .env. This is not the same thing as the site tool's group_* actions, which nest a real site under another's subdomain and regenerate vhosts and certs — reach for group_* when a site should be served at <label>.<main>.test, and for workspace when the user just wants their site list organised
  • assign takes sites (names or domains) and a workspace, creating it if new; workspace: "none" ungroups them. move reorders a workspace with a zero-based position
  • delete drops the workspace and ungroups its members; no site is touched
Key conventions
  • Pass action on every tool; path is optional on most and defaults to the directory the assistant was opened in
  • Discover before acting: site list for sites, worker list for a site's workers, service preset_list before preset_install, exec vendor_bins before vendor_run
  • On a fresh Laravel clone (DB_CONNECTION=sqlite), call db set before env setup to choose a database deliberately, then run framework setup
  • Domain conflicts on link: a link drops a domain another site owns (reported in warnings) and registers the survivors, falling back to <dirname>.<tld>; .lerd.yaml is untouched. domain_add still hard-errors
  • Custom APP_URL: env setup writes <scheme>://<primary-domain>; override via app_url in .lerd.yaml (committed) or the per-machine sites.yaml entry, then re-run env setup
  • Built-in service hosts follow lerd-<name> (e.g. lerd-mysql, lerd-redis, lerd-postgres); default DB credentials are username root, password lerd
  • Custom container sites (Node.js, Python, Go, …) — mandatory order: (1) write a Containerfile (default Containerfile.lerd); (2) write .lerd.yaml with container: {port: <N>} (plus optional domains, services, secured); (3) configure the project's .env with service hosts (lerd-mysql, etc.) and start needed services via service start; (4) call site link. Never link before steps 1–3 or the site registers as PHP-FPM; if that happens, site unlink, write the files, then link again
  • Worker unit names follow lerd-<worker>-<site> (per-worktree: lerd-<worker>-<site>-<branch>)
  • Host tools (CLI-only): diag status reports Composer, fnm and mkcert against the versions lerd pins, and flags any that differ. Applying an update is lerd tools:update, which has no tool here, so tell the user to run it rather than looking for an action
  • Sharing a site is CLI-only and deliberate: lerd share (ngrok, cloudflared, Expose, serveo, localhost.run, Pinggy) and the dashboard's share menu put a site on the public internet, the same menu's public share serves it through the user's own reverse proxy on a base domain they control instead of a tunnel service, and lerd lan:expose puts it on the local network. None is exposed here, so never claim you can share a site; hand the user the command and let them decide

© liberusoftware, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

Just SKILL.md in .claude/skills/lerd of liberusoftware/real-estate-laravel.

Open the folder on GitHubat commit 8d7119e

Used in 2 other repositories

We found 2 copies of this SKILL.md (exact, near-identical or edited) in other folders. This page covers the copy in liberusoftware/real-estate-laravel, which our catalogue first saw on October 7, 2026.

Compare with similar skills

Lerd next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Lerd compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Lerd this skillliberusoftware/real-estate-laravel112—~7.8kAutomated safety check: WarnMIT
Laravel Best Practicesanonaddy/anonaddy4.9k13 repos~1.2kAutomated safety check: PassMIT
MCP Developmentcachethq/core230—~1.4kAutomated safety check: PassMIT
Laravel ToolingHoangNguyen0403/agent-skills-standard571—~760Automated safety check: PassMIT
MCP Developmentcoollabsio/coolify63k1 repos~949Automated safety check: PassMIT
Configuring Horizoncoollabsio/coolify63k4 repos~898Automated safety check: PassMIT

Similar skills

  • Laravel Best Practices

    anonaddy/anonaddy

    Apply this skill whenever writing, reviewing, or refactoring Laravel PHP code.

    4.9k GitHub starsUsed in 13 repos~1.2k tokens
    Backend & APIsAuto-check passed
  • MCP Development

    cachethq/core

    A skill your agent uses for Cachet's Laravel MCP server. An agent skill from cachethq/core.

    230 GitHub stars~1.4k tokensUpdated 3 days ago
    Backend & APIsAuto-check passed
  • Laravel Tooling

    HoangNguyen0403/agent-skills-standard

    Configure Laravel ecosystem with custom Artisan commands, Vite asset bundling, Pint code styling, and Horizon queue monitoring.

    571 GitHub stars~760 tokensUpdated yesterday
    Backend & APIsAuto-check passed
  • MCP Development

    coollabsio/coolify

    A skill your agent uses for Laravel MCP development. An agent skill from coollabsio/coolify.

    63k GitHub starsUsed in 1 repo~949 tokens
    Frontend & DesignAuto-check passed
  • Configuring Horizon

    coollabsio/coolify

    A skill your agent uses whenever the user mentions Horizon by name in a Laravel context.

    63k GitHub starsUsed in 4 repos~898 tokens
    Backend & APIsAuto-check passed
  • Geoflow

    yaojingang/GEOFlow

    Operate/develop GEOFlow CLI/Laravel/admin/API, topics/专题 and topic tasks, theme libraries/replication, sites/leads/Agent, channel sync and legacy yao-geoflow-cli/design/template migration.

    3.8k GitHub stars~722 tokensUpdated today
    Backend & APIsAuto-check passed

More from liberusoftware/real-estate-laravel

  • Pest Testing

    liberusoftware/real-estate-laravel

    A skill your agent uses for Pest PHP testing in Laravel projects only.

    112 GitHub starsUsed in 1 repo~1.8k tokens
    Auto-check passed
  • Octane Development

    liberusoftware/real-estate-laravel

    A skill your agent uses when working with Laravel Octane, a long-running PHP worker server (Swoole, FrankenPHP, RoadRunner) where the application boots once and serves many requests instead of…

    112 GitHub stars~1.8k tokensUpdated 3 days ago
    Auto-check passed

Questions about Lerd

What does Lerd do?

Manage the lerd local PHP development environment via MCP tools: run framework console commands (artisan, bin/console, etc.), manage services, start/stop queue workers, run composer, manage Node.js…. Lerd is an agent skill from liberusoftware/real-estate-laravel.js versions, and inspect site status.

When should I use Lerd?

Lerd fits situations like: tasks that involve Backend development; tasks that involve MCP servers; tasks that involve Query optimization.

How do I install Lerd in Claude Code?

Run `npx skills add liberusoftware/real-estate-laravel --skill lerd -a claude-code`. Or copy the skill folder (.claude/skills/lerd in liberusoftware/real-estate-laravel) into .claude/skills/lerd in your project. Claude Code loads it when a task matches its description.

How do I install Lerd in Codex?

Run `npx skills add liberusoftware/real-estate-laravel --skill lerd -a codex`. Or copy the skill folder (.claude/skills/lerd in liberusoftware/real-estate-laravel) into .agents/skills/lerd in your project. Codex loads it when a task matches its description.

Can I use Lerd in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add liberusoftware/real-estate-laravel --skill lerd -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/lerd, .gemini/skills/lerd, .github/skills/lerd and .opencode/skills/lerd in your project.

What does Lerd need to run?

Going by SKILL.md and its folder, Lerd needs the command-line tools its instructions call (npm, composer, pnpm, yarn, nvm and node) and credentials named APP_KEY, STRIPE_SECRET, STRIPE_SECRET_KEY and STRIPE_API_KEY. Our summary lists: Node.js.

Does Lerd access the network?

SKILL.md contains no URLs. Its commands use npm and git, which can reach the network depending on how they are called. This is read from the text; nothing was executed.

Is Lerd safe to install?

Our automated static check of SKILL.md flagged 1 warning(s): mentions a credentials file (ssh keys, cloud or package-manager tokens). Read the flagged lines before installing; the check is not a guarantee either way.

What licence does Lerd use?

Lerd is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Lerd use?

About 7.8k tokens (SKILL.md is roughly 31k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.

What are the alternatives to Lerd?

Skills that share tags, products or a category with Lerd: Laravel Best Practices (anonaddy/anonaddy, 4.9k stars), MCP Development (cachethq/core, 230 stars), Laravel Tooling (HoangNguyen0403/agent-skills-standard, 571 stars) and MCP Development (coollabsio/coolify, 63k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Lerd?

liberusoftware (a GitHub organization) maintains it in liberusoftware/real-estate-laravel, which has 112 GitHub stars. The repository holds 3 skills in this directory. The repository was last updated on October 5, 2026.

Source: liberusoftware/real-estate-laravel on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.