isapp/laravel-forge-mcp

Native Laravel MCP server for managing Laravel Forge servers, sites and deployments via the Forge API v2.

Maintainers

Package info

github.com/isap-ou/laravel-forge-mcp

pkg:composer/isapp/laravel-forge-mcp

Statistics

Installs: 32

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 1

v1.3.0 2026-06-08 19:27 UTC

README

Tests Lint Latest Version PHP Version License

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:

  1. Open your Forge account dashboard and click API.
  2. Click Create token, give it a name and an optional expiration date.
  3. Select the scopes the token should have, then click Add token.
  4. 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 pass organizationSlug to 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 — when true, 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_environmentget_site_environment returns a site's .env contents, 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 (via report()), so internal details (hostnames, URLs) are not leaked into the model context. Set to true in 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 load and reset deployment state endpoints 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.