vinkius/laravel-mcp-connect
A Laravel package for connecting your application to Model Context Protocol (MCP) servers and tools. It streamlines MCP integration so Laravel apps can expose resources, prompts, and tools to AI clients with familiar configuration and an elegant developer experience.
Architecture fit. This is a thin, opinionated SDK that wraps a remote MCP catalog (Vinkius) behind a Laravel service provider, a Mcp facade, an HTTP transport, and 13 readonly DTOs. Architecturally it is a classic "vendor SDK in a framework package" shape: config file, service provider, facade, HTTP client with retry, event dispatcher hooks, and Artisan commands. It introduces no middleware, no persistence layer, no queue workers, and no schema migrations, so it composes with existing Laravel apps rather than reshaping them. The dual surface (authenticated Catalog + public Marketplace) is the single most important design decision: the Marketplace half is usable without credentials, which lowers the bar for spikes and demos, while the Catalog half is where auth, governance, and metering presumably live. That split needs to be reflected in our own architectural boundaries — anything built on the public surface must not be assumed to be production-grade.
Integration feasibility. Low friction to install (composer require plus one vendor:publish), low friction to call (facade + commands), moderate friction to operate responsibly (config, token management, cache tuning, event listeners). The Artisan commands are a genuine accelerant for evaluation: mcp:browse, mcp:search, mcp:tools, and mcp:inspect let an engineer or PM validate the value proposition in an afternoon without writing application code. The 59 Pest tests / 191 assertions is a credible but not exceptional signal for a v1.0.0 — it tells us the happy paths and DTO mapping are covered, not that failure modes against a live third-party catalog are hardened.
Technical risk. The dominant risk is external dependency on a single commercial vendor for both the catalog and the transport contract. Every meaningful capability here is a remote call; there is no local fallback, no offline mode, and no documented degradation story. Secondary risks: the retry and "structured error classification" behavior is ours to configure but theirs to define — we need to know whether error classes are stable API or advisory hints. Read-through cache with per-endpoint TTLs is welcome, but caching a governed catalog raises staleness questions (a deactivated server still appearing as available). Event-driven observability is a strength: ToolExecuted and ServerActivated give us a hook for audit and cost attribution without patching the package. Finally, "3,400+ governed MCP servers" is a marketing figure; we have no evidence of quality distribution, uptime SLA, or what "governed" contractually means.
Key questions.
Stack fit. Requires PHP 8.2+ and Laravel 11 or 12. That is a narrow, modern window: fine for greenfield and recently upgraded services, a blocker for any app still on Laravel 10 or PHP 8.1. The readonly DTOs imply PHP 8.1+ idioms throughout, so there is no graceful path for older runtimes. For teams already on the supported matrix, fit is essentially perfect — it is a first-party-style package with a facade, config, and commands, which is exactly the shape Laravel developers expect.
Migration path. There is nothing to migrate from, which is both the opportunity and the risk. The realistic adoption path is additive: install alongside existing tooling, use the Marketplace surface (no token) to explore, then gate any Catalog usage behind a feature flag and a dedicated service class of our own that wraps the facade. Wrapping rather than calling Mcp:: directly across the codebase preserves the option to swap vendors or self-host later, and it gives us a single place to enforce allowlists and audit. Avoid letting Artisan command behavior leak into production runbooks — commands are for humans, not schedulers.
Compatibility. Two compatibility surfaces matter. First, framework compatibility: Laravel 11/12 only, which should be stated explicitly as a constraint in any architecture decision record. Second, contract compatibility with the remote API: we should pin the package to a caret range, subscribe to releases, and treat minor bumps as requiring a smoke test against the live catalog, not just a green CI run. The per-endpoint cache TTLs are config we should set deliberately rather than accept defaults, and cache keys should be namespaced so a shared Redis instance does not collide with application data.
Sequencing.
mcp:browse and mcp:search against the public Marketplace, no credentials, no commitment. Timebox to a day.McpGateway interface, an allowlist of approved servers, and audit listeners on ToolExecuted / ServerActivated.Maintenance. The package itself is small and, at v1.0.0, has just crossed into a stability commitment — which historically is when APIs actually start to churn as real-world usage lands. Budget for a dependency bump cadence tied to Laravel's release train: each Laravel major will likely require a package major. Our wrapper layer absorbs most of that, which is the main argument for building it on day one rather than retrofitting.
Support. Support is vendor-mediated. There is no indication of an LTS policy, a security disclosure process, or a support tier. Internally, ownership should sit with the backend/platform team that owns integrations, not with individual feature teams who happen to call the facade. The six Artisan commands are a real operational asset for debugging — mcp:inspect and mcp:analytics in particular shorten incident triage — but they should be documented as read-only diagnostics.
Scaling. Client-side scaling is trivial: stateless HTTP calls plus a read-through cache. The scaling ceiling is entirely on the vendor side — rate limits, per-token quotas, and catalog query latency are outside our control. Cache TTLs are therefore a capacity lever as much as a freshness lever, and the two pull against each other: longer TTLs reduce vendor load but increase the window in which a deactivated or newly governed server is misrepresented. Plan for a circuit breaker at the wrapper layer so vendor degradation does not translate into our own thread exhaustion, and cap retries to avoid amplifying an outage.
Failure modes. Enumerate them explicitly rather than discovering them: (1) vendor outage — every Catalog call fails; Marketplace calls may survive independently, which argues for not assuming the two surfaces share fate; (2) auth expiry or rotation — Bearer token failures need to surface as a distinct, actionable error class, not a generic 401; (3) rate limiting — retry storms are the classic self-inflicted wound here; (4) stale cache serving a retired server; (5) DTO mapping breaks when the remote payload adds or shifts a field; (6) misbehaving third-party MCP server executing a tool with our data. Modes 5 and 6 are the ones the test suite almost certainly does not cover, since it cannot exercise a live, adversarial catalog.
Ramp-up. Very low for a Laravel developer: one composer command, one publish, and the facade reads naturally. The Artisan commands make the concept legible to non-engineers in minutes, which is useful for stakeholder demos. The real ramp-up cost is conceptual, not syntactic — teams must internalize that this is a remote, vendor-governed surface with its own trust boundary, not a local library. Budget half a day of onboarding per engineer plus a short written policy on which servers may be activated and what data may be sent through a tool execution. That policy, not the code, is what will determine whether this package is a durable asset or a compliance incident waiting to be scheduled.
How can I help you explore Laravel packages today?