Weave Code
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

Mcp Laravel Package

laravel/mcp

Build MCP servers inside Laravel so AI clients can safely interact with your app via the Model Context Protocol. Includes tools to expose app capabilities, run requests, and integrate quickly using Laravel’s conventions and docs.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require laravel/mcp
    

    Publish the configuration:

    php artisan vendor:publish --provider="Laravel\MCP\McpServiceProvider"
    
  2. Configure MCP Server: Edit config/mcp.php to define your server's metadata (e.g., name, description, version).

  3. Define a Tool: Create a tool using the mcp:tool Artisan command:

    php artisan mcp:tool make:tool GetUserData
    

    This generates a stub in app/Mcp/Tools/GetUserData.php. Implement the handle() method to define the tool's logic:

    public function handle(ToolRequest $request): ToolResponse
    {
        $user = User::find($request->id);
        return new ToolResponse($user->toArray());
    }
    
  4. Register the Tool: Bind the tool in app/Providers/McpServiceProvider.php:

    public function registerTools()
    {
        $this->mcp->tool('get_user_data', GetUserData::class);
    }
    
  5. Run the MCP Server: Start the server with:

    php artisan mcp:serve
    

    By default, it runs on http://localhost:8000/.well-known/mcp.


First Use Case: Exposing a Laravel Model as an MCP Tool

  1. Create a Tool:

    php artisan mcp:tool make:tool GetPost
    

    Implement the tool to fetch a blog post:

    public function handle(ToolRequest $request): ToolResponse
    {
        $post = Post::findOrFail($request->post_id);
        return new ToolResponse($post->toArray());
    }
    
  2. Test with an AI Client: Use an AI client (e.g., LangChain) to call the tool:

    {
      "jsonrpc": "2.0",
      "method": "get_post",
      "params": { "post_id": 1 },
      "id": 1
    }
    

Key Configuration

  • Server Metadata: Define in config/mcp.php:
    'server' => [
        'name' => 'My Laravel App',
        'description' => 'A Laravel-powered MCP server',
        'version' => '1.0.0',
    ],
    
  • OAuth: Configure OAuth clients in config/mcp.php under the oauth key if using authentication.

First Debugging Step

Use the mcp:inspect command to debug tool registrations:

php artisan mcp:inspect

This lists all registered tools and their metadata.


Implementation Patterns

1. Tool Development Workflow

a. Tool Creation

  • Use the mcp:tool Artisan commands to scaffold tools:
    php artisan mcp:tool make:tool CreateUser
    php artisan mcp:tool make:resource UserResource
    
  • Tools should extend Laravel\MCP\Tools\Tool and implement handle(ToolRequest): ToolResponse.

b. Resource Integration

  • For resources (e.g., REST-like endpoints), use mcp:resource:
    public function toResponse(ToolRequest $request): ToolResponse
    {
        return new ToolResponse($this->user->toArray());
    }
    
  • Resources support URI templates (e.g., /users/{id}).

c. Authentication

  • Use middleware to protect tools:
    public function handle(ToolRequest $request): ToolResponse
    {
        $request->authenticate(); // Throws if unauthenticated
        // ...
    }
    
  • For OAuth, configure clients in config/mcp.php and use the withOAuth() helper.

2. Client-Side Integration

a. Named Clients

  • Register named clients in config/mcp.php:
    'clients' => [
        'default' => [
            'url' => 'http://localhost:8000/.well-known/mcp',
            'timeout' => 5.0,
        ],
    ],
    
  • Use the client in code:
    $response = Mcp::client('default')->call('get_user_data', ['id' => 1]);
    

b. Streaming Responses

  • For tools returning streams (e.g., large files), use StreamableResponse:
    public function handle(ToolRequest $request): ToolResponse
    {
        return new ToolResponse(
            new StreamableResponse(
                Storage::disk('public')->readStream('large-file.pdf')
            )
        );
    }
    

c. Prompts and UI

  • Use assertStructuredContent() to validate tool responses:
    public function handle(ToolRequest $request): ToolResponse
    {
        return new ToolResponse($request->assertStructuredContent(function ($data) {
            return User::validate($data);
        }));
    }
    
  • For UI tools, return HTML responses with Mcp\Resources\HtmlResource.

3. Testing Tools

a. Unit Testing

  • Use ToolTestCase:
    use Laravel\MCP\Testing\ToolTestCase;
    
    class GetUserDataTest extends ToolTestCase
    {
        public function test_handle()
        {
            $response = $this->callTool('get_user_data', ['id' => 1]);
            $response->assertSuccessful();
        }
    }
    

b. Integration Testing

  • Test with the MCP client:
    public function test_client_calls_tool()
    {
        $response = Mcp::client('test')->call('get_user_data', ['id' => 1]);
        $this->assertEquals(['name' => 'John'], $response->data());
    }
    

4. Advanced Patterns

a. Dynamic Tool Registration

  • Register tools dynamically in a service provider:
    public function registerTools()
    {
        foreach (config('mcp.tools') as $name => $class) {
            $this->mcp->tool($name, $class);
        }
    }
    

b. Tool Chaining

  • Chain tools by calling one tool from another:
    public function handle(ToolRequest $request): ToolResponse
    {
        $user = $this->mcp->call('get_user_data', ['id' => $request->user_id]);
        return new ToolResponse($user->data()['posts']);
    }
    

c. Error Handling

  • Centralize error handling in a middleware:
    public function handle(ToolRequest $request, Closure $next)
    {
        try {
            return $next($request);
        } catch (\Exception $e) {
            return new ToolResponse([
                'error' => $e->getMessage(),
            ], 500);
        }
    }
    

5. Performance Optimization

a. Caching Tool Lists

  • Enable caching for tool lists in config/mcp.php:
    'cache' => [
        'enabled' => true,
        'ttl' => 60, // Cache for 60 seconds
    ],
    

b. Octane Support

  • Use Octane for high-performance tool execution:
    php artisan octane:start --server=swoole
    
  • Ensure tools are stateless or use shared memory for caching.

Gotchas and Tips

Pitfalls

  1. Circular References in Tool Responses:

    • Avoid returning circular references (e.g., User with a posts relationship that loops back to User). Use ->toArray() or ->makeHidden() to break cycles.
    • Fix: Use Laravel\MCP\Tools\Resource::makeHidden() or ->toArray():
      return new ToolResponse($user->makeHidden(['password'])->toArray());
      
  2. OAuth Redirect URIs:

    • If using OAuth, ensure redirect URIs in config/mcp.php match the AI client's callback URL exactly (including http vs https).
    • Fix: Use dynamic ports for localhost:
      'oauth' => [
          'clients' => [
              'client_id' => [
                  'redirect_uri' => 'http://localhost:3000/callback',
              ],
          ],
      ],
      
  3. JSON-RPC ID Handling:

    • The id field in JSON-RPC requests must be a string or integer. Non-string/non-integer IDs (e.g., null or objects) will cause TypeError.
    • Fix: Validate client requests:
      if (!is_string($request->id) && !is_int($request->id)) {
          throw new \InvalidArgumentException('JSON-RPC id must be a string or integer.');
      }
      
  4. Tool Registration Order:

    • Tools registered later may override earlier ones if they share
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.
codraw/framework-extra-bundle
codraw/messenger
codraw/security
codraw/mailer
codraw/contracts
codraw/profiling
codraw/dependency-injection
codraw/tester
codraw/core
nexmo/api-specification
capell-app/block-library
axium/identity
cetria/laravel-dummy-models
cetria/reflection-helper
agropredict/sso-auth-bundle
evolvestudio/spam-protection
datacore/hub-sdk
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony