mcp/sdk
The official PHP SDK for the Model Context Protocol: a framework-agnostic API for building MCP servers and clients in PHP, with tools, resources, prompts, STDIO and HTTP transports, sessions, authorization, and support for both protocol eras.
OAuthProxyMiddleware, ClientRegistrationMiddleware, ClientRegistrarInterface, JwksProvider, OIDC metadata policies are removed). Decision: pick an external IdP (Auth0, Authentik, Keycloak, Cognito) and treat the MCP server as a protected resource. Budget for this — it's an integration, not a config toggle.Builder::setSessionLock() with FileSessionLock (single host) or SymfonyLockSessionLock (shared store, e.g. Redis). If you run Laravel Octane, Horizon workers, or multiple pods, you must plan a shared lock + session store or accept 503s under contention.2026-07-28 over stdio and HTTP. Plan a client-compatibility matrix rather than assuming one protocol revision.TransportInterface::send() semantics changed, AccessToken is threaded through processInput()/handleMessage()/onMessage(), JwtTokenValidator is final with a single issuer, and requireScopes() is replaced by ScopePolicy. Decision: pin the SDK version, schedule a migration spike before any production commitment, and assume another BC break before 1.0.ScopePolicy (per-method/per-tool 403 insufficient_scope with hierarchies), https-enforced ProtectedResourceMetadata, always-on Host validation with explicit allowedOrigins, and CORS preflight no longer 401-ing behind auth. This is sellable to security review boards — previously a blocker for enterprise deals.SymfonyLockSessionLock).2026-07-28) for heterogeneous agent clients.-32020/-32022 error codes) over a bespoke HTTP API.[BC Break] tags.SessionLockTimeoutException → 503 under concurrent same-session load."The MCP PHP SDK lets us expose our existing PHP/Laravel backend to AI agents without a rewrite. v0.9.0 is the release that makes it production-credible: it fixes concurrent sessions, streaming, and response routing under real load, and it tightens security to an enterprise-acceptable posture — scoped authorization, strict host/origin validation, standards-compliant protected-resource metadata.
What that means commercially:
Bottom line: buy the protocol, build the tools, rent the identity."
"v0.9.0 is a hardening release with real BC breaks — read the migration list before upgrading.
Wins:
Builder::setSessionLock(); FileSessionLock for single-host, SymfonyLockSessionLock for shared/Redis), partial Session::save() so parallel requests stop clobbering each other, UUID request IDs so parallel elicitations/progress tokens can't cross, and correct fiber resumption on stdio.Psr16SessionStore returns 503 (retryable) instead of a misleading 404.ScopePolicy as the third AuthorizationMiddleware arg with scope hierarchies, https-enforced ProtectedResourceMetadata, DnsRebindingProtectionMiddleware always validating Host plus separate allowedOrigins, and CORS preflight no longer 401-ing. PassthroughMiddleware lets you opt out of the default stack explicitly.2026-07-28; StatelessAwareTransportInterface::setHandshakeVersions() declares what you negotiate.Migration checklist (all [BC Break]):
Uuid — update sendRequest(), checkResponse(), handleFiberYield(), and transport response finders.TransportInterface::send() now receives every response of a non-suspending handler; the outgoing queue only carries server-initiated requests/notifications. Custom transports must deliver each message (a batch yields several).AccessToken is threaded through processInput(), handleMessage(), handlePostRequest(), and the onMessage() listener (4th arg). Replace OAuthRequestMetaMiddleware with RequestContext::getAccessToken(); AuthorizationResult::allow() takes an AccessToken.JwtTokenValidator is final, single-issuer, takes a key set (CachedKeySet); fromIssuer() caches in PSR-6 and refetches on unknown kid. requireScopes() → ScopePolicy. alg allowlist enforced.OAuthProxyMiddleware, ClientRegistrationMiddleware, ClientRegistrarInterface, JwksProvider*, OidcDiscoveryInterface — move that to your IdP.DnsRebindingProtectionMiddleware signature changed; allowedOrigins is the new second arg and defaults to empty.ProtectedResourceMetadata requires $resource, derives its path (RFC 9728 §3.1), and requires https except loopback.Pinning guidance: treat the SDK as an internal dependency — wrap it behind our own tool-registration interface so the next [BC Break] is a localized change, not a codebase-wide sweep."
"The DX is unchanged at the happy path — the complexity moved into correctness and security.
#[McpTool]
public function generateReport(User $user): string { ... }
What you get under the hood in 0.9.0:
202 for response/notification-only POSTs), both speaking the handshake era and 2026-07-28.AccessToken and enforce scopes with ScopePolicy; the SDK no longer proxies OAuth or registers clients — point it at your IdP's JWKS.Practical advice: pin the version, run the migration checklist from the changelog, and keep tool handlers thin so the next BC break is a one-file fix. Perfect for CLI tools, APIs, and legacy classes you want to expose to agents — just don't expect 1.0 stability yet."
How can I help you explore Laravel packages today?