Fixing Laravel Boost in Windsurf: A Global MCP Setup Guide

Fixing Laravel Boost in Windsurf: A Global MCP Setup Guide

If you’ve tried adding Laravel Boost as an MCP server in Windsurf and hit “cannot initialize server”, you’re not alone.

The most common cause is simple:

  • Windsurf often starts MCP servers from a working directory that is NOT your Laravel project root.
  • So a “normal” MCP command like php artisan boost:mcp fails because artisan isn’t in the current directory (or it runs with the wrong PHP).

In other words: this is usually not a Boost problem — it’s a Windsurf MCP launch context problem.

When Laravel announced Boost, I was thrilled.
I rushed over to the docs expecting to see a simple “Use this with Windsurf” section.
But as I kept scrolling… that smile gradually dropped from my face.
I saw Cursor, Junie, and a bunch of familiar integrations — but not Windsurf.
So I kept searching until I landed on a setup that’s boringly reliable.

This tutorial shows a robust approach that works across all your Laravel projects:

  • Install Boost per project (required)
  • Add a Windsurf MCP server that calls a wrapper script
  • The wrapper script finds the correct Laravel project and runs php artisan boost:mcp

If you keep multiple Laravel projects open at the same time, you’ll also see how to configure per-project MCP entries so each project stays isolated.

Note: While we’re configuring Windsurf “globally” so it can work with any project, Laravel Boost itself must still be installed locally in every Laravel project via Composer. This wrapper simply helps Windsurf find the correct local installation.

Bonus:

  • Add Herd MCP to Windsurf too (handy if you use Herd for local sites/PHP)

The target architecture (what we’re building)

Windsurf can launch MCP servers from arbitrary directories, so the reliable design is to put an adaptive layer in front of Boost:

Windsurf (any cwd)
  -> wrapper script (stable entrypoint)
       -> find Laravel project root (locate artisan)
       -> choose correct PHP (prefer Herd / isolated PHP)
       -> exec: php artisan boost:mcp

Once you understand that flow, every config choice in this guide makes sense.

Prerequisites

  • You have Windsurf installed
  • You have PHP installed (Herd/Homebrew/Linux packages/Windows PHP)
  • Python 3 is recommended (only needed for the optional auto-detection fallback; without it the script falls back to $PWD / SITE_PATH)
  • You have at least one Laravel project

Install Boost in each Laravel project (required)

In every Laravel project you want Boost to work with:

composer require laravel/boost --dev
php artisan boost:install

Then verify inside that project:

php artisan boost:mcp

If this fails, fix your Laravel app boot/dependencies first. MCP depends on the app being able to boot.

Understanding Windsurf MCP config files

Windsurf follows the Claude Desktop MCP config schema.

  • Windsurf Editor:

    • macOS/Linux: ~/.codeium/mcp_config.json
    • Windows: C:Users.codeiummcp_config.json
  • Windsurf JetBrains plugin (PhpStorm/IntelliJ):

    • macOS/Linux: ~/.codeium/windsurf/mcp_config.json
    • Windows: C:Users.codeiumwindsurfmcp_config.json

Warning: If you edit the wrong file, you’ll keep seeing “cannot initialise server” even though the JSON looks correct.

Quick way to confirm you’re editing the right file:

  • Temporarily point the command to a definitely-invalid path (or rename your wrapper script).
  • Refresh MCP servers in Windsurf.
  • If the error message doesn’t change, you’re editing the wrong config file.

For the rest of this guide:

  • If you’re using the Windsurf Editor, edit ~/.codeium/mcp_config.json
  • If you’re using Windsurf inside PhpStorm, edit ~/.codeium/windsurf/mcp_config.json

Tip: You can include multiple servers (Boost, Herd, etc.) inside the same mcpServers object.

The Fix: Use a Wrapper Script

Instead of configuring laravel-boost as:

{
  "command": "php",
  "args": ["artisan", "boost:mcp"]
}

…we configure it to run a wrapper script. The wrapper script:

Phase 1 — Locate the Laravel project root

  • Search upward for artisan
  • Fall back to other hints like SITE_PATH
  • (Optional) Use Windsurf trackers to guess active workspaces (requires Python 3)

Phase 2 — Choose the right PHP

  • Prefer Herd’s per-site PHP when available (so isolated sites use their own PHP)
  • Fall back to a usable php binary

Phase 3 — Launch MCP

  • exec herd php artisan boost:mcp (preferred)
  • or exec artisan boost:mcp

Using the right PHP version per project (Herd + alternatives)

One subtle issue when you have lots of Laravel projects is PHP version drift: one project might require PHP 8.1 while another needs PHP 8.3.

Herd supports per-site PHP versions via “isolation”. Once a project is isolated, Herd can automatically run the correct PHP when you execute commands from that project.

Set a PHP version for a project:

cd /path/to/your-project
herd isolate 8.3

Confirm what PHP Herd will use for that project:

cd /path/to/your-project
herd which-php

That’s why the wrapper script in this tutorial prefers:

herd php artisan boost:mcp

If you’re not using Herd

You still have options:

  • asdf / mise / phpenv

    • These can select PHP based on the current directory (e.g. .tool-versions / .mise.toml).
    • The key is ensuring the tool’s “shims” are available to Windsurf (non-interactive process).
  • Docker / Laravel Sail

    • You can run Boost using the project’s containerized PHP instead of your host PHP.
    • This is heavier, but very consistent across teams.
  • One global PHP

    • If all your projects support the same PHP version, the simplest option is to keep one PHP installed globally (Herd/Homebrew/etc.).

macOS / Linux Setup

Step 1: Create the wrapper script

Create a file at:

  • macOS/Linux: ~/.codeium/laravel-boost-mcp.sh

Then make it executable:

chmod +x ~/.codeium/laravel-boost-mcp.sh

Step 2: Add laravel-boost to Windsurf MCP config

Edit:

  • Windsurf Editor (macOS/Linux): ~/.codeium/mcp_config.json
  • Windsurf JetBrains plugin (macOS/Linux): ~/.codeium/windsurf/mcp_config.json

Add (or replace) your laravel-boost entry:

{
  "mcpServers": {
    "laravel-boost": {
      "command": "https://dev.to/Users//.codeium/laravel-boost-mcp.sh",
      "args": ["${workspaceFolder}"],
      "disabled": false,
      "env": {}
    }
  }
}

If you work on multiple Laravel projects in parallel, create one Boost entry per project (same wrapper, different env), and give each entry a unique server name.

{
  "mcpServers": {
    "laravel-boost-project-name": {
      "command": "https://dev.to/Users//.codeium/laravel-boost-mcp.sh",
      "args": ["${workspaceFolder}"],
      "disabled": false,
      "env": { "LARAVEL_PROJECT_ROOT": "https://dev.to/path/to/project-name" }
    },
    "laravel-boost-another-project": {
      "command": "https://dev.to/Users//.codeium/laravel-boost-mcp.sh",
      "args": ["${workspaceFolder}"],
      "disabled": false,
      "env": { "LARAVEL_PROJECT_ROOT": "https://dev.to/path/to/another-project" }
    }
  }
}

Notes:

  • Keep your other MCP servers in the same file; just add this entry inside the existing mcpServers object.
  • The path must be the full absolute path to the script.

If you’re adding multiple MCP servers, don’t replace the whole file—just add laravel-boost inside the existing mcpServers object.

Step 3: Restart/refresh MCP servers in Windsurf

  • Open Windsurf settings
  • Go to MCP / Tools
  • Click refresh (or restart Windsurf)

Step 4: Quick sanity check

Run:

~/.codeium/laravel-boost-mcp.sh --check

You should see:

  • what directory it decided is the Laravel project root (artisan_dir)
  • which php binary it found as a fallback (php_bin)
  • whether Herd CLI is available (herd_bin)
  • what Herd would use as the PHP for that project (herd_which_php) if available

If this output looks correct but Windsurf still can’t start the server, jump to the Troubleshooting section below.

Step 5: Test the wrapper in real-world scenarios

This wrapper is designed to behave well even when Windsurf starts it from a “random” working directory.

Scenario A: Not a Laravel project (expected: skipped)

From any folder that is not a Laravel app:

~/.codeium/laravel-boost-mcp.sh --check

Expected output includes:

  • skipped (no Laravel project detected; artisan not found)

Scenario B: Laravel project without Boost installed (expected: skipped)

Inside a Laravel project that does NOT have Boost:

cd /path/to/laravel-project
~/.codeium/laravel-boost-mcp.sh --check

Expected output includes:

  • skipped (Boost not installed in this project)

Scenario C: Laravel project with Boost + Herd per-site PHP (expected: Herd isolated PHP)

Inside a Laravel project with Boost installed:

cd /path/to/laravel-project
composer require laravel/boost --dev
herd isolate 8.3
herd which-php
~/.codeium/laravel-boost-mcp.sh --check

Expected output includes:

  • herd_bin: ...
  • herd_which_php: ... (matching your isolated version)

Then, to confirm it can actually start, run the wrapper (this is a long-running process; stop with Ctrl+C):

~/.codeium/laravel-boost-mcp.sh

Final macOS/Linux wrapper script (multi-project safe)

Save as: ~/.codeium/laravel-boost-mcp.sh

#!/usr/bin/env bash
set -euo pipefail

find_artisan_dir() {
  local dir="$1"
  while true; do
    if [[ -f "$dir/artisan" ]]; then
      printf "%s" "$dir"
      return 0
    fi

    local parent
    parent="$(dirname "$dir")"
    if [[ "$parent" == "$dir" ]]; then
      return 1
    fi
    dir="$parent"
  done
}

find_php() {
  if command -v php >/dev/null 2>&1; then
    command -v php
    return 0
  fi

  local candidates=(
    "https://dev.to/opt/homebrew/bin/php"
    "https://dev.to/usr/local/bin/php"
    "$HOME/Library/Application Support/Herd/bin/php"
  )

  local p
  for p in "${candidates[@]}"; do
    if [[ -x "$p" ]]; then
      printf "%s" "$p"
      return 0
    fi
  done

  return 1
}

get_windsurf_active_paths() {
  local py=""
  if [[ -x "https://dev.to/usr/bin/python3" ]]; then
    py="https://dev.to/usr/bin/python3"
  elif command -v python3 >/dev/null 2>&1; then
    py="$(command -v python3)"
  else
    return 0
  fi

  "$py" - <<'PY'
from pathlib import Path
import re

base = Path.home() / '.codeium' / 'windsurf' / 'code_tracker' / 'active'
if not base.exists():
    raise SystemExit(0)

paths = []
for f in base.rglob('*_mcp.json'):
    try:
        b = f.read_bytes()
    except Exception:
        continue

    for m in re.finditer(br'file:///[^x00s"]+', b):
        u = m.group(0).decode('utf-8', 'ignore')
        if u.startswith('file:///'):
            paths.append(u[7:])

seen = set()
for p in paths:
    if p in seen:
        continue
    seen.add(p)
    print(p)
PY
}

collect_candidate_start_dirs() {
  local candidates=()

  candidates+=("$PWD")

  if [[ -n "${SITE_PATH:-}" ]]; then
    candidates+=("$SITE_PATH")
  fi

  local p
  while IFS= read -r p; do
    [[ -n "$p" ]] && candidates+=("$p")
  done < <(get_windsurf_active_paths 2>/dev/null || true)

  printf "%sn" "${candidates[@]}" | awk 'NF && !seen[$0]++'
}

start_dir="${PWD}"
artisan_dir=""

check_mode=0
root_arg=""
if [[ "${1:-}" == "--check" ]]; then
  check_mode=1
  shift
fi

if [[ -n "${1:-}" ]]; then
  root_arg="$1"
  shift
fi

if [[ -n "${root_arg}" ]] && [[ "${root_arg}" != "${workspaceFolder}" ]] && [[ "${root_arg}" != "${workspaceFolder}" ]] && [[ "${root_arg}" != "${workspaceRoot}" ]] && [[ "${root_arg}" != "${workspaceRoot}" ]]; then
  if [[ -d "${root_arg}" ]]; then
    artisan_dir="$(find_artisan_dir "${root_arg}" 2>/dev/null || true)"
  fi
fi

if [[ -z "${artisan_dir}" ]] && [[ -n "${LARAVEL_PROJECT_ROOT:-}" ]]; then
  if ! artisan_dir="$(find_artisan_dir "${LARAVEL_PROJECT_ROOT}" 2>/dev/null)"; then
    echo "laravel-boost MCP: LARAVEL_PROJECT_ROOT set but artisan not found." >&2
    echo "- LARAVEL_PROJECT_ROOT: ${LARAVEL_PROJECT_ROOT}" >&2
    exit 1
  fi
fi

if [[ -z "${artisan_dir}" ]]; then
  while IFS= read -r candidate; do
    if artisan_dir="$(find_artisan_dir "$candidate" 2>/dev/null)"; then
      break
    fi
  done < <(collect_candidate_start_dirs)
fi

if [[ -z "$artisan_dir" ]]; then
  echo "laravel-boost MCP: skipped (no Laravel project detected; artisan not found)." >&2
  echo "- starting directory: $start_dir" >&2
  if [[ -n "${SITE_PATH:-}" ]]; then
    echo "- SITE_PATH: ${SITE_PATH}" >&2
  fi
  exit 0
fi

if [[ ! -d "${artisan_dir}/vendor/laravel/boost" ]]; then
  echo "laravel-boost MCP: skipped (Boost not installed in this project)." >&2
  echo "- artisan_dir: ${artisan_dir}" >&2
  echo "Tip: run 'composer require laravel/boost --dev' in this project." >&2
  exit 0
fi

php_bin=""
if ! php_bin="$(find_php)"; then
  echo "laravel-boost MCP: php binary not found in PATH or common locations." >&2
  echo "Ensure PHP is installed and available to your IDE (Herd/Homebrew)." >&2
  exit 1
fi

if [[ "${check_mode}" == "1" ]]; then
  echo "laravel-boost MCP wrapper check" >&2
  echo "- starting directory: ${start_dir}" >&2
  if [[ -n "${root_arg}" ]]; then
    echo "- root_arg: ${root_arg}" >&2
  fi
  if [[ -n "${LARAVEL_PROJECT_ROOT:-}" ]]; then
    echo "- LARAVEL_PROJECT_ROOT: ${LARAVEL_PROJECT_ROOT}" >&2
  fi
  if [[ -n "${SITE_PATH:-}" ]]; then
    echo "- SITE_PATH: ${SITE_PATH}" >&2
  fi
  echo "- artisan_dir: ${artisan_dir}" >&2
  echo "- php_bin: ${php_bin}" >&2
  herd_bin=""
  if command -v herd >/dev/null 2>&1; then
    herd_bin="$(command -v herd)"
  fi
  if [[ -n "${herd_bin}" ]]; then
    echo "- herd_bin: ${herd_bin}" >&2
    herd_php="$(cd "${artisan_dir}" && herd which-php 2>/dev/null || true)"
    if [[ -n "${herd_php}" ]]; then
      echo "- herd_which_php: ${herd_php}" >&2
    fi
  else
    echo "- herd_bin: " >&2
  fi
  exit 0
fi

cd "$artisan_dir"
if command -v herd >/dev/null 2>&1; then
  exec herd php artisan boost:mcp
fi

exec "$php_bin" artisan boost:mcp

Add Herd MCP to Windsurf (macOS, Linux, Windows notes)

If you use Laravel Herd, you can also add Herd’s MCP server to Windsurf.

What Herd MCP does

Herd MCP provides tools around Herd’s local dev environment (sites, PHP versions, etc.).

Important OS note

  • macOS: Fully supported.
  • Windows: Fully supported.
  • Linux: Herd is not typically available, so you can skip this section.

Step 1: Create a Herd wrapper script

Create a file at:

  • macOS: ~/.codeium/herd-mcp.sh

Make it executable:

chmod +x ~/.codeium/herd-mcp.sh

Step 2: Add the herd server in Windsurf MCP config

Edit:

  • macOS: ~/.codeium/windsurf/mcp_config.json

Add (or update) this entry inside mcpServers:

{
  "mcpServers": {
    "herd": {
      "command": "bash",
      "args": [
        "https://dev.to/Users//.codeium/herd-mcp.sh",
        "${workspaceFolder}"
      ],
      "disabled": false,
      "env": {}
    }
  }
}

Why run it with bash?

  • On macOS, some security/xattr quirks can cause direct execution errors.
  • Running via bash

Previous Post

Best Way to Produce YouTube Videos in Foreign Languages

Next Post

Your Enterprise Application Performance Isn’t Scaling: Here’s Why

Related Posts