Search by

builtbyberry / laravel-swarm-mcp

dberry37388

Read-only Model Context Protocol (MCP) server for Laravel Swarm — expose durable run history, durable-run inspection, and audit-outbox health as MCP Resources over the official laravel/mcp package.

v0.3.0 2026-10-06 12:14 UTC

README

tests

A read-only Model Context Protocol server for Laravel Swarm, built on the official laravel/mcp package. It exposes a swarm's durable run history, durable-run inspection, and audit-outbox health as MCP Resources, so any MCP-compatible AI client — Claude, Cursor, and others — can observe your swarm runs.

Read-only by design. This release exposes observability Resources only and registers zero Tools. It can observe swarm runs but can never pause, resume, cancel, or signal them. Operator control is a deliberately deferred later minor (see Read-only by design).

It wraps Laravel Swarm's public display-read contracts (introduced in core v0.19.0) — ReadableRunHistoryStore, InspectsDurableRuns, and ReadableAuditOutbox — so every read is display-decrypted and degrade-safe by construction: an undecryptable field (e.g. after an APP_KEY rotation) comes back as null with an *_available: false flag rather than raw sw0: ciphertext or a failed read.

Requirements

  • PHP ^8.4
  • builtbyberry/laravel-swarm ^0.19 through ^0.28
  • laravel/mcp ^1.0

Version 0.2 requires native Laravel MCP 1.x. See Upgrading for the dependency and client protocol change. The six read-only resources retain their URIs; no tools or prompts are registered.

Installation

composer require builtbyberry/laravel-swarm-mcp

Optionally publish the config file:

php artisan vendor:publish --tag="swarm-mcp-config"

Configuration

config/swarm-mcp.php:

Key Default Description
server.enabled true Master switch for the observability server.
server.name Laravel Swarm Display name reported to MCP clients.
transports.stdio.enabled true Expose the server over stdio (local / agent-host).
transports.http.enabled false Expose the server over the networked HTTP transport. Off by default.
transports.http.path swarm-mcp Route path for the HTTP transport.
authentication.middleware ['auth:sanctum'] Middleware applied to the HTTP transport route.
resources.* true Toggle individual resource groups (run_history, durable_inspection, audit_outbox).

Connecting an MCP client

stdio (default)

The server is registered under the handle laravel-swarm and started with the laravel/mcp command:

php artisan mcp:start laravel-swarm

Point your MCP client at that command. For example, a Claude Desktop entry:

{
  "mcpServers": {
    "laravel-swarm": {
      "command": "php",
      "args": ["artisan", "mcp:start", "laravel-swarm"]
    }
  }
}

HTTP (Streamable)

Set transports.http.enabled to true. The server is then reachable at the configured path (default POST /swarm-mcp) behind the configured authentication middleware. A networked caller must authenticate — the default guard is auth:sanctum (your application provides Sanctum). See Authorization.

Resources

URI Backed by Returns
swarm://runs ReadableRunHistoryStore::query() The most recent runs — a lean, decryption-free projection.
swarm://runs/{runId} ReadableRunHistoryStore::findForDisplay() A single run with its steps; sealed fields degrade per field.
swarm://durable-runs/{runId} InspectsDurableRuns::inspect() Assembled durable-run state: waits, signals, progress, children, branches, hierarchical outputs.
swarm://audit-outbox/health ReadableAuditOutbox::healthSummary() Outbox availability + pending / dead-letter / reserved counts.
swarm://audit-outbox/queue/{state} pending() / deadLettered() The pending or dead-lettered queue (metadata + last_error only).
swarm://audit-outbox/records/{id} ReadableAuditOutbox::record() A single outbox row with its full display-decrypted payload.

Display-safe reads

Every resource resolves the bound public contract — never the @internal SwarmPersistenceCipher. Sealed payloads are opened through the display path, which honors swarm.persistence.decrypt_failure_policy and degrades per field: an undecryptable value becomes null with an explicit *_available: false flag (output_available, context_available, payload_available, …). A rotated APP_KEY or a single poison row therefore never throws, never aborts the read, and never leaks sw0: ciphertext to the client. The audit-outbox reads are pure SELECTs — they cannot drain or mutate the outbox that swarm:relay --type=audit drains.

Read-only by design

v0.1.0 is intentionally Resources-only. The server registers no Tools, so an AI client can read swarm state but cannot act on it. Exposing the operator control verbs (pause / resume / cancel / signal) to an autonomous agent is a subtle surface — it requires a per-run authorization callback and deliberately excludes fleet-wide batch verbs — and is planned for a later minor behind an explicit opt-in. Until then, this package is a safe, observe-only window into your swarms.

Authorization

The server authenticates a networked caller (via the configured authentication.middleware), but it is agnostic about which runs a caller may read — scoping run visibility to a tenant or user is your application's responsibility. This release exposes read-only data only.

Testing

composer test       # Pest
composer analyse    # PHPStan (level 8)
composer lint       # Pint

CI retains historical core lanes and the published core v0.25.0 baseline. The v0.2.0 compatibility work was validated against pinned core v0.26.0 / AI ^0.11.2 and core v0.27.0 / AI ^1.0 candidates at minimum and current stable dependencies. v0.3.0 extends this to the frozen core v0.28.0 candidate (269f749, release/v0.28.0) with native AI 1.x, adding two native1-028 lanes for twenty runtime lanes overall. All runtime lanes use native MCP ^1.0; the existing branch-naming gate remains. Tests exercise authenticated native HTTP discovery, exact primitive inventory, all six resource reads, protocol errors and guest rejection. See native MCP compatibility evidence for source pins and reproduction.

Candidate metadata was temporary CI input; those lanes are historical prepublication evidence. Fresh Packagist-only installation after core and companion publication remains a separate shipping gate.

License

The MIT License (MIT). Please see the License File for more information.