Skip to main content

What is MCP?

The Model Context Protocol (MCP) is a specification for AI clients (such as Claude, Cursor, and GitHub Copilot) to communicate with applications through a standardized protocol. By implementing an MCP server, you can allow AI agents to access data in your Laravel application or perform actions on your behalf.
Laravel MCP is an official package added in Laravel 13. Distributed as laravel/mcp, it provides the features you need to build an MCP server.
An MCP server can provide three main capabilities.

Installation

Install the package via Composer.
After installation, run the vendor:publish Artisan command to generate the routes/ai.php file.
This command creates the routes/ai.php file. This is where you register your MCP servers.

Creating a server

Generate a server class with the make:mcp-server Artisan command.
The server class is created in the app/Mcp/Servers directory.

Registering a server

Once you’ve created a server, register it in routes/ai.php. There are two registration types: web servers and local servers.

Web servers

A web server is accessed via HTTP POST requests. This is ideal for remote AI clients or web-based integrations.
You can apply middleware just like a regular route.

Local servers

A local server runs as an Artisan command. Use it to integrate with local AI clients like Claude Desktop.
Local servers are typically started automatically by the MCP client. You don’t need to run the mcp:start Artisan command manually.

Tools

A tool is a function the AI client can call. You can implement data retrieval, integrations with external APIs, database operations, and more.

Creating a tool

Generate a tool class with the make:mcp-tool Artisan command.
Register the new tool in the server’s $tools property.
Here’s a basic tool implementation.

Tool name and description

Default names and titles are generated from the class name. CurrentWeatherTool becomes name current-weather and title Current Weather Tool. You can customize both with the Name and Title attributes.
The tool’s description (Description) is not generated automatically. It’s essential for the AI model to understand how to use the tool, so always provide a meaningful description.

Input schema

Use the schema method to define the input parameter schema. You can specify types and constraints using Laravel’s JSON schema builder.

Output schema

The outputSchema method lets you define the structure of the response. This makes it easier for AI clients to parse the response.

Validation

You can use Laravel’s standard validation features inside the handle method.
When validation fails, the AI client uses the error message to retry. Provide specific, actionable error messages.

Dependency injection

Tools are resolved through Laravel’s service container, so you can type-hint dependencies in the constructor or handle method.

Annotations

You can add annotations to tools to provide additional information about the tool’s behavior to the AI client.
The available annotations are:

Conditional registration

Implement shouldRegister to conditionally register the tool at runtime.
Returning false hides the tool from the AI client.

Responses

A tool must return a Laravel\Mcp\Response instance.
Returns structured data that’s easy for AI clients to parse.
Sends progress updates in real time during long-running operations.

Prompts

A prompt is a reusable prompt template. You can use them to provide standardized boilerplate queries that AI clients use to interact with language models.

Creating a prompt

Register it in the server’s $prompts property.

Prompt arguments

Use the arguments method to define the prompt’s parameters.

Validation

Prompt arguments are automatically validated based on their definitions, but you can also apply more complex validation rules. Laravel MCP integrates seamlessly with Laravel’s validation features. You can validate arguments inside a prompt’s handle method.
When validation fails, the AI client uses the error message to retry. Provide specific, actionable messages.

Dependency injection

Prompts are resolved through Laravel’s service container, so you can type-hint dependencies in the constructor or handle method.
You can also type-hint on handle, and the service container will resolve and inject dependencies automatically.

Conditional registration

Implement shouldRegister to conditionally register a prompt at runtime.
Returning false hides the prompt from the AI client and prevents it from being called.

Prompt responses

A prompt’s handle method can return user messages and assistant messages. Use asAssistant() to mark a message as coming from the assistant.

Resources

Resources are data or information that AI clients can load as context. You can provide documents, configuration information, dynamic data, and any other information that improves the quality of the AI’s response.

Creating a resource

Register it in the server’s $resources property.

URIs and MIME types

By default, the URI is auto-generated from the class name (for example, weather://resources/weather-guidelines). You can customize this with the Uri and MimeType attributes.

Resource templates

To define a dynamic resource with URI variables, implement the HasUriTemplate interface.
Variables from the URI are automatically merged into the request and can be read with get.

Resource requests

Unlike tools and prompts, resources cannot define an input schema or arguments. However, you can still access request information via the request object inside handle.

Resource dependency injection

Resources are resolved through Laravel’s service container, so you can type-hint dependencies in the constructor or handle method.
You can also type-hint on handle, and the service container will resolve and inject dependencies automatically.

Resource annotations

You can attach audience, priority, and last-modified annotations to a resource.

Conditional resource registration

Implement shouldRegister to conditionally register a resource at runtime.
Returning false hides the resource from the AI client and prevents access.

Resource responses

A resource must return a Laravel\Mcp\Response instance. For text content, use the text method.
Use the resourceLink method to return a resource link. Unlike an embedded resource, it returns a URI pointer that the AI client will fetch independently.
You can also pass a registered resource class or instance. The URI, name, title, description, and MIME type are inherited automatically.

Blob response

To return binary content, use the blob method. Set the MIME type using the #[MimeType] attribute on the resource.

Error response

Use the error method to indicate an error.

Apps

Laravel MCP supports MCP Apps, an extension of the Model Context Protocol that lets tools render interactive HTML applications inside a sandboxed iframe in supported hosts. This enables dashboards, forms, visualizations, and other rich experiences that go beyond plain text responses. An MCP app is composed of two pieces working together.
  • App resource — returns the self-contained HTML for the application.
  • Tool — linked to the app resource with the #[RendersApp] attribute. When the tool is invoked, the host fetches and renders the linked resource.

Creating an app resource

You can create an app resource with the make:mcp-app-resource Artisan command.
This command creates two files: a PHP class in app/Mcp/Resources and a Blade view in resources/views/mcp. The view name is inferred from the class name. For example, WeatherDashboardApp maps to mcp.weather-dashboard-app.
AppResource extends the base Resource class and automatically applies the ui:// URI scheme and text/html;profile=mcp-app MIME type required by the MCP Apps specification. Like other resources, you must register it in the server’s $resources array. The generated Blade view uses the <x-mcp::app> component. This component renders a complete HTML document that includes the bundled client-side MCP SDK.
The global createMcpApp function is provided by the bundled SDK. It handles the iframe’s connection to the server, applies the host theme, and exposes helpers such as callServerTool, sendMessage, and openLink along with event callbacks. See the MCP Apps specification for the full client-side API.

Rendering an app from a tool

To display an app resource, link it from a tool with the #[RendersApp] attribute. When the tool is invoked, Laravel MCP includes the resource’s URI in the tool metadata so the host can render the app inside a sandboxed iframe.
When an AppResource is registered, Laravel MCP automatically advertises the io.modelcontextprotocol/ui capability. No additional server configuration is required.

App tool visibility

Each #[RendersApp] tool can restrict its callers via the visibility argument. This is useful for hiding private app-only tools the UI calls to load or update data from the model.
The Visibility enum has two cases, Model and App, and defaults to both. Use [Visibility::App] for backend actions that only the UI calls directly, and [Visibility::Model] to make the tool unavailable to the UI.

App configuration

The #[AppMeta] attribute on an app resource configures the iframe’s Content Security Policy, browser permissions, and any library scripts to include in the view’s <head>.
The Library enum ships preconfigured CDN scripts for common frontend libraries such as Library::Tailwind and Library::Alpine, and the CDN origins are automatically merged into the CSP. The Permission enum covers browser permissions such as Camera, Microphone, Geolocation, and ClipboardWrite.
For dynamic configuration, override the resource’s appMeta method using the AppMeta, Csp, and Permissions fluent builders from the Laravel\Mcp\Server\Ui namespace.

Developing apps with Boost

Laravel MCP includes a dedicated Boost skill reference for building MCP Apps. When Laravel Boost is installed, AI coding agents can invoke the mcp-development skill and automatically generate an app resource, its Blade view, and the linked tool. For the complete protocol reference (including client-side API and schema details), see the official MCP Apps documentation.

Metadata

You can attach the MCP spec’s _meta field to tool, resource, and prompt responses.
To attach metadata to the entire response envelope, use Response::make.
To attach metadata to the tool, resource, or prompt class itself, define a $meta property.

Icons

MCP clients can display icons for the server and its primitives. Use the Icon attribute to declare icons on the server, tools, resources, and prompts.
The Icon attribute is repeatable, so you can declare multiple icons to provide different sizes or light/dark theme variants. Alternatively, you can override the icons method to define icons programmatically. This is useful when icons depend on runtime conditions.
Icons defined via attributes and the icons method are combined automatically. Icon paths are resolved as follows.
  • Paths with a URI scheme such as https: or data: are used as-is.
  • Relative paths are resolved to URLs using Laravel’s asset helper.

Authentication

Web servers can be authenticated with Laravel’s standard middleware.

Sanctum

Token authentication using Laravel Sanctum. The MCP client sends an Authorization: Bearer <token> header.

OAuth 2.1

OAuth authentication using Laravel Passport. This suits situations that call for stronger security.
When using OAuth, publish the Passport authorization view and register it in a service provider.

Authorization

You can retrieve the authenticated user via $request->user() and perform authorization checks inside tools and resources.

MCP client

Laravel MCP doesn’t just help you build servers — it also provides a client for connecting to other MCP servers. With the client, you can discover and invoke tools exposed by external MCP servers. This is especially useful when providing external MCP server capabilities to your AI agents.

Connecting to a server

Use Client::web to connect to an HTTP-accessible MCP server, passing the server URL.
To connect to a local MCP server that starts as a command, use Client::local, passing the command and its arguments.
The client connects lazily and establishes the connection the first time you list or invoke tools. To manage the connection manually, use the connect, connected, ping, and disconnect methods.
Use withTimeout to customize the request timeout.

Named clients

Instead of constructing a client each time, you can register a reusable named client. This is typically done in a service provider’s boot method using the Mcp facade.
Once registered, you can resolve the client by name.
A named client is resolved once per request and automatically disconnected at the end of the request lifecycle.

Client authentication

To connect to a web MCP server protected by a bearer token, use the withToken method. You can pass a token string or a closure that resolves lazily.
To connect to a server protected by OAuth 2.1, use the withOAuth method.
If the MCP server supports dynamic client registration, you can omit clientId and clientSecret. The client will register itself automatically.
Next, register the OAuth routes for the named client in routes/ai.php with oAuthRoutesFor. The closure receives the client name and a TokenSet after the authorization code has been exchanged for an access token.
This registers two named routes: the connect route (mcp.oauth.{client}.connect) that redirects the user to the authorization server, and the callback route (mcp.oauth.{client}.callback) that exchanges the authorization code and calls your handler. Both use the web middleware group by default (which you can override via the middleware argument). To begin the authorization flow, redirect the user to the connect route.

Tools

The tools method fetches tools exposed by the MCP server. It returns a collection keyed by name.
The client automatically handles pagination and fetches every tool. Use the limit argument to cap the number of results.
To invoke a tool, use callTool and pass the tool name and an argument array. The returned ToolResult instance carries the response.
You can also invoke it directly from a listed tool instance.
If you’re building an agent with the Laravel AI SDK, you can hand the MCP client’s tools directly to the agent so the model can call them while responding to a prompt. See the MCP tools section of the AI SDK docs for details.

Prompts

The prompts method fetches prompts exposed by the MCP server. It returns a collection keyed by name.
The client automatically handles pagination and fetches every prompt. Use limit to cap the number of results.
To retrieve a prompt, use getPrompt, passing the prompt name and an argument array. The returned PromptResult instance carries the generated messages.

Resources

The resources method fetches resources exposed by the MCP server. It returns a collection keyed by URI.
The client automatically handles pagination and fetches every resource. Use limit to cap the number of results.
To read a resource, use readResource and pass the resource URI. The returned ResourceReadResult instance carries the resource content.

Testing

MCP Inspector

Use the interactive MCP Inspector debugging tool to verify your MCP server.
When you run the command, MCP Inspector starts and you can copy the client configuration. If you’ve configured authentication middleware, include the Authorization header when connecting.

Unit tests

You can write unit tests against tools, resources, and prompts.
You can test prompts and resources the same way.
Use actingAs to run as an authenticated user.
The main assertion methods are:
Use assertHasErrors / assertHasNoErrors to check for errors.
You can verify the tool, resource, or prompt’s name, title, and description.
Use assertSentNotification and assertNotificationCount to verify streaming response notifications.
Use dd or dump to debug the response contents.
Last modified on August 2, 2026