isapp / laravel-forge-mcp
Native Laravel MCP server for managing Laravel Forge servers, sites and deployments via the Forge API v2.
Requires
- php: ^8.2
- illuminate/contracts: ^12.0|^13.0
- illuminate/support: ^12.0|^13.0
- laravel/forge-sdk: ^4.0
- laravel/mcp: ^0.7
Requires (Dev)
- laravel/pint: ^1.18
- mockery/mockery: ^1.6
- orchestra/testbench: ^10.0|^11.0
- phpunit/phpunit: ^11.0
This package is auto-updated.
Last update: 2026-06-08 21:47:28 UTC
README
A native Laravel MCP server for managing
Laravel Forge servers, sites and deployments. It is a Composer-installable
replacement for the Node @bretterer/forge-mcp-server package and talks to the
Forge API v2 through the official
laravel/forge-sdk.
Contents
Requirements
- PHP 8.2+
- Laravel 12 or 13
laravel/mcp^0.7- A Laravel Forge API v2 token (see API token)
Installation
composer require isapp/laravel-forge-mcp
The service provider is auto-discovered.
Configuration
The package reuses the standard laravel/forge-sdk configuration. Add a
forge entry to config/services.php:
'forge' => [ 'token' => env('FORGE_API_TOKEN'), // Optional. Forge API v2 scopes calls to an organization. Leave this out // to resolve it automatically; set it when the token can access more than // one organization. 'organization' => env('FORGE_ORG_SLUG'), // Optional safety/behaviour flags (all default to false): // Expose only read-only tools; deploy, reboot, deployment-script update // and quick-deploy toggle are not registered. 'read_only' => env('FORGE_MCP_READ_ONLY', false), // Register the get_site_environment tool. It returns the site's .env // (secrets), so it is disabled unless you opt in. 'expose_environment' => env('FORGE_MCP_EXPOSE_ENVIRONMENT', false), // Return raw Forge/SDK exception messages to the client. When false the // client gets a generic message and the full error goes to the log. 'verbose_errors' => env('FORGE_MCP_VERBOSE_ERRORS', false), ],
FORGE_API_TOKEN=your-forge-api-token # FORGE_ORG_SLUG=your-org-slug # FORGE_MCP_READ_ONLY=true # FORGE_MCP_EXPOSE_ENVIRONMENT=true # FORGE_MCP_VERBOSE_ERRORS=true
API token
This package talks to the organization-scoped Forge API v2. To create a token:
- Open your Forge account dashboard and click API.
- Click Create token, give it a name and an optional expiration date.
- Select the scopes the token should have, then click Add token.
- Copy the generated token into
FORGE_API_TOKEN.
Scopes. Forge lets you restrict a token to specific scopes. This package needs only the following:
| Scope | Used for |
|---|---|
server:view |
Reading servers, sites, deployments and logs (all the list_* / get_* tools). |
site:manage-deploys |
deploy_site, get_deployment_script, update_deployment_script, toggle_quick_deploy. |
server:manage-services |
reboot_server. |
site:manage-environment |
get_site_environment (unverified — reading the env file may also be covered by server:view). |
organization:view |
Only when FORGE_ORG_SLUG is not set — the package lists your organizations to resolve the slug automatically. Not needed if you set the slug explicitly. |
If you only use the read-only tools, server:view is enough (plus
organization:view when the slug is auto-resolved). You do not need
server:manage-logs — that scope only clears logs, while this server only reads
them. A token missing a required scope makes the corresponding tool return a
Forge authorization error.
The legacy Forge API v1 is being retired (scheduled 30 June 2026). This package only uses API v2, so create the token from the current dashboard as described above.
Organization slug
Forge API v2 requires an organization slug on every server and site call. When
services.forge.organization is empty the package resolves it automatically:
- exactly one organization on the token → it is used and cached;
- multiple organizations → set
FORGE_ORG_SLUG, or passorganizationSlugto an individual tool call.
Safety flags
This server hands an AI agent control over your Forge infrastructure, so it
ships with conservative defaults. All three flags live under services.forge
and default to false:
read_only— whentrue, only read-only tools are registered. The state-changing tools (deploy_site,reboot_server,update_deployment_script,toggle_quick_deploy) are neither listed nor callable. Use this when you only want the agent to observe.expose_environment—get_site_environmentreturns a site's.envcontents, which include secrets, so it is disabled by default. Enable it only when you understand that the secrets are sent to the MCP client/model.verbose_errors— by default a failed Forge call returns a generic message to the client and logs the full exception (viareport()), so internal details (hostnames, URLs) are not leaked into the model context. Set totruein development to return the raw exception message instead.
There are no per-call confirmation prompts at the package level — gate risky
operations with read_only or by trusting the operator/client.
Usage
The package registers a local (stdio) MCP server named forge. Start it with:
php artisan mcp:start forge
Point your MCP client at that command. For example, in a .mcp.json:
{
"mcpServers": {
"forge": {
"command": "php",
"args": ["artisan", "mcp:start", "forge"]
}
}
}
Inspect it interactively with:
php artisan mcp:inspector forge
Read-only mode
To let an agent observe but never change Forge state, run the server with
read_only enabled. MCP clients can pass it as an environment
variable on the server command:
{
"mcpServers": {
"forge": {
"command": "php",
"args": ["artisan", "mcp:start", "forge"],
"env": { "FORGE_MCP_READ_ONLY": "true" }
}
}
}
With this set, deploy_site, reboot_server, update_deployment_script and
toggle_quick_deploy are not registered and cannot be called. (This relies on
the read_only key being wired into config/services.php as shown in
Configuration.)
Tools
| Tool | Description |
|---|---|
list_servers |
List all servers in the organization. |
get_server |
Get a server by ID. |
list_sites |
List sites on a server. |
get_site |
Get a site by ID. |
get_site_environment |
Read a site's environment (.env) file. ⚠️ Exposes secrets; disabled unless expose_environment is true. |
get_site_nginx_access_log |
Nginx access log for a site. |
get_site_nginx_error_log |
Nginx error log for a site (diagnose 5xx errors). |
get_site_application_log |
Application log for a site (diagnose app errors). |
deploy_site |
Trigger a deployment. |
get_deployments |
Deployment history for a site. |
get_deployment |
A single deployment, including status. |
get_deployment_log |
Output log for a deployment (diagnose failures). |
get_deployment_script |
Get the deployment script. |
update_deployment_script |
Update the deployment script. |
toggle_quick_deploy |
Enable/disable quick deploy (push-to-deploy). |
reboot_server |
Reboot a server. |
get_server_log |
Server-level log by key (diagnose server issues). |
Every tool accepts an optional organizationSlug argument to override the
resolved organization for that call.
Forge API v2 note: the old API v1
server loadandreset deployment stateendpoints do not exist in API v2 and are intentionally not provided.
Testing
composer test # run the test suite composer lint # apply coding standards (Laravel Pint) composer lint:test # check coding standards without modifying files
Contributing
See AGENTS.md for architecture, conventions and how to add a tool. Pull requests run the test matrix (PHP 8.2–8.4 × Laravel 12–13) and Pint via GitHub Actions.
License
The MIT License (MIT). See LICENSE.