Laravel MCP hit 1.0 on September 14, with the announcement thread landing the next morning. This is a protocol-level upgrade, not a polish release: the package now speaks MCP revision 2026-07-28 by default, drops server-side session state, and adds two features (searchable tool catalogs and cache hints) that address the two biggest costs of running MCP servers in production, context bloat and repeated work. If you have a 0.x server live, the upgrade guide is longer than you would expect for a point-zero, and a chunk of it lands in your test suite.
What shipped
Protocol 2026-07-28 and the end of initialize. The initialize handshake is gone, replaced by server/discover. Every modern request carries the protocol version and client capabilities in its own params._meta. Legacy clients that still open with initialize keep working: the server answers with 2025-11-25 or 2025-06-18 and serves the rest of that client's requests without the new metadata requirements.
Stateless servers. Request::sessionId(), Request::setSessionId(), and the MCP-Session-Id header are removed. Every HTTP request and stdio message is processed independently. There is no replacement; if you need to correlate calls, pass your own identifier through the arguments or _meta. The SessionInitialized event goes with it.
Searchable tool catalogs. Instead of advertising every tool in tools/list, you nest the rarely-used ones under a ToolSearch::class key in the server's $tools array. The server then exposes two tools of its own: search_tools, which searches by name, description, and input schema, and execute_tools, which invokes one or more results. Limits live in mcp.tool_search.max_tool_calls and mcp.tool_search.max_output_bytes.
protected array $tools = [
CurrentWeatherTool::class,
ToolSearch::class => [
HistoricalWeatherTool::class,
WeatherAlertsTool::class,
],
];
Cache hints. Discovery, primitive listings, and resource reads now carry cache hints. The default is private with a zero TTL. A #[Cacheable(ttlMs: 60_000, scope: CacheScope::Public)] attribute on the server sets a default, a cacheHints() method overrides it per method, and the same attribute on a Resource class overrides both. Hints are advisory, and Laravel's own MCP client now honors them.
OAuth tightening. PKCE is mandatory: OAuthClient::redirect() throws if the authorization server's metadata omits code_challenge_methods_supported, with no opt-out. Dynamic Client Registration is deprecated in favor of Client ID Metadata Documents, where client_id is an HTTPS URL pointing at a JSON document your app now serves at /mcp/oauth/{client}/client-metadata.json. That change also fixes a bug where every redirect() performed a fresh registration.
Smaller items. MCP Apps moves under capabilities.extensions via protected array $extensions = [Extension::Ui]. A new ErrorCode enum adds -32020 (header mismatch) and -32022 (unsupported protocol version). Test helpers gain assertNotRegistered and assertions for registered tools, prompts, and resources. A conformance suite ships in the repo for local runs, and Laravel 11 compatibility was restored during the beta.
Our take
This is a good 1.0. The team chose to track the protocol closely rather than freeze an older revision behind a stable API, and the two headline features solve production problems rather than demo problems.
Searchable tool catalogs are the one we would adopt first. Dumping 40 or 100 tool definitions into every request is the single largest source of wasted tokens we see in agent workloads, and it gets worse as a product matures. Splitting tools into "always advertised" and "searchable" is a design decision you now make per server with one array key. Make it early, because retrofitting means re-evaluating which tools the model was actually finding on its own.
Statelessness is the right default for anything behind a load balancer, and it removes a category of bugs where a session lives on one node and the next request lands on another. But it is a removal, not a deprecation. Anyone who used sessionId() for rate limiting or audit correlation needs a new plan before upgrading, not after.
The honest trade-offs:
- Your tests will break. The new
ValidateMcpHeadersmiddleware applies to everyMcp::web()route, and the guide is explicit that this includes your application's tests. EachpostJsonto an MCP endpoint needsMCP-Protocol-VersionandMcp-Methodheaders, plusMcp-Namefor tool calls, prompt gets, and resource reads, plus the_metablock in the body. A mismatch is an HTTP 400. The fix is mechanical, but it touches every test that hits the endpoint. - PKCE has no escape hatch. Third-party authorization servers that do not publish
code_challenge_methods_supportednow throw at redirect time. For those, the guide points to pre-issued credentials viaclientCredentials(), which changes the auth model for that integration. - Client secrets become nullable. Under Client ID Metadata Documents your app is a public client and
clientSecretisnull. Any column that stores it must allow null, and code passing it torefreshCredentials()must accept null. Miss this and the first modern server you connect produces a database error. APP_URLis now load-bearing. The client metadata document is built fromAPP_URL, not from the incoming request. A wrong value in production yields aclient_idthe authorization server cannot fetch.
Practical recommendations
Read the upgrade guide before composer update, not after. It is specific and well organized, and the items marked "Likelihood of Impact: High" are exactly that.
Audit for sessionId() and SessionInitialized first. Those are the two hard removals. Everything else in the guide has a mechanical fix; these two need a design decision.
Upgrade in a branch and run the conformance suite. It ships in the repo now. Use it as the acceptance gate instead of your own smoke tests.
Move rarely-used tools into a ToolSearch catalog as part of the same PR. You are already editing the server class. Keep the three to five tools the model reaches for constantly, and search the rest.
Set a real Cacheable TTL on tools/list. The default is zero, so clients re-fetch on every turn. Thirty seconds is long enough to matter and short enough to be safe.
Originally referenced: Laravel MCP 1.0 is here on X (@laravel). Details verified against the 1.0 upgrade guide and the Laravel MCP documentation.
If you are running an MCP server on Laravel and want a second pair of eyes on the 1.0 upgrade, or help deciding which tools belong in a searchable catalog, get in touch.



