Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Mcp Laravel Package

mevisoft/laravel-mcp

Laravel MCP helps you build Model Context Protocol servers in Laravel, exposing tools, resources, and prompts to AI clients through an expressive PHP API. It follows Laravel conventions and Artisan workflows so you can ship MCP endpoints quickly.

View on GitHub
Deep Wiki
Context7

Getting Started

Install the package with Composer and publish its configuration:

composer require mevisoft/laravel-mcp
php artisan vendor:publish --tag="laravel-mcp-config"

Where to look first, in order:

  1. config/mcp.php — server name/version, transport(s), route/middleware registration, and any tool-discovery paths. This file tells you the shape of everything else.
  2. The package's contracts directory (src/Contracts or similar) — the Tool, Resource, and Prompt interfaces define what a handler must implement (name, description, input schema, handle method).
  3. The registered routes (php artisan route:list | grep mcp) — confirms whether an HTTP/SSE endpoint is exposed and under which middleware.
  4. The bundled Artisan command (usually php artisan make:mcp-tool / mcp:serve) — the fastest way to see a correct, working skeleton.

First use case: wrap one read-only, high-value query as a Tool — e.g. search_orders that accepts a status and date range and returns a trimmed array of order summaries. Register it on the default server, connect from Claude Desktop (or Cursor / the MCP Inspector) over stdio locally, confirm it appears in the tool list, then point the same server at a staging HTTP endpoint behind Sanctum. Read-only first: you get the full loop (schema → validation → serialization → client) with zero blast radius.

Implementation Patterns

Thin tool, fat action. A tool class should only describe and validate. Delegate the real work to an existing Action/Service/Query object so the same logic is reachable from HTTP, jobs, and MCP:

public function handle(array $arguments): array
{
    $data = validator($arguments, [
        'status' => ['nullable', Rule::in(['open', 'paid', 'cancelled'])],
        'limit'  => ['nullable', 'integer', 'min:1', 'max:50'],
    ])->validate();

    return SearchOrders::run($data, $this->user())->toArray();
}

Bind identity, not parameters. Resolve the acting user from the authenticated token/session and inject it, rather than accepting user_id as a tool argument. This keeps Gate/Policy checks, global scopes, and tenancy resolution intact — an MCP call should be indistinguishable from a normal web request in the authorization path.

Resources for reads, tools for writes. Expose Eloquent models as Resources (list/read with cursors) and reserve Tools for actions with side effects. This maps cleanly onto how clients present the two, and it keeps your destructive surface small and auditable.

Transport per environment. stdio for local development and desktop clients; Streamable HTTP/SSE behind an authenticated route group for remote clients. Keep the HTTP group under the same middleware stack as your API (auth:sanctum, throttle) so rate limiting and token expiry apply for free.

Test at two levels. Unit-test the tool class directly (schema validation, happy path, authorization failure), and add one integration test that POSTs a JSON-RPC tools/call to the endpoint and asserts the envelope. The MCP Inspector is the right tool for manual smoke tests, but it should not be your only coverage.

Instrument every invocation. Log tool name, argument keys (not values, where sensitive), duration, and outcome. The caller is an LLM — you need a trail to explain why a write happened. Queue anything above a few seconds and return a job handle the model can poll.

Gotchas and Tips

  • Descriptions are the API. Tool names, descriptions, and JSON Schemas are the prompt. Vague descriptions cause the model to ignore a tool or call it with garbage. Write them for a smart colleague who has never seen your codebase, and include an example in the description.
  • Never echo to stdout under stdio. The stdio transport is a JSON-RPC stream; a stray dump(), dd(), or echo corrupts it and the client disconnects with an opaque error. Route logs to files/stderr and keep LOG_STACK off stdout.
  • Long-lived process semantics. A stdio server boots once and serves many calls. Config is read at boot, DB connections persist, and container singletons stay warm — do not cache the authenticated user or request-scoped state across calls, or you will leak identity between sessions.
  • Serialization leaks. Returning an Eloquent model directly can expose $hidden-adjacent attributes and produces enormous payloads. Always return explicit arrays or API Resources with a selected column set.
  • Cap everything. Models will happily request limit=100000 or a one-year date range. Clamp page size server-side and return a cursor; treat every argument as untrusted input.
  • Client timeouts are short. Most clients give up around 30–60s. Synchronous fan-out over several models will fail — queue it and return a handle.
  • Streaming behind a proxy. SSE/Streamable HTTP needs proxy_buffering off (nginx) and output buffering disabled; otherwise responses arrive in one lump or not at all. Test through the actual proxy, not just artisan serve.
  • Error text is user-facing. Exceptions are surfaced to the model as feedback. Write them as instructions ("status must be one of: open, paid, cancelled"), not as stack traces.
  • Config caching. Run php artisan config:clear after editing config/mcp.php; some boot-time reads silently ignore changes under a cached config.
  • 1.0.0 is the stabilization point. The release notes for this version are only a changelog link, so read the changelog and README rather than assuming the pre-1.0 API carried over — pin the version in composer.json and re-run your integration test on each bump.
  • Extension points worth knowing: tool discovery paths (so package tools can live outside your app namespace), middleware on the MCP route group (auth, tenancy, audit), and the transport layer itself if you need to front the server with your own gateway.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core