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 Client Laravel Laravel Package

redberry/mcp-client-laravel

Laravel client for the Model Context Protocol (MCP). Supports JSON-RPC 2.0 over Streamable HTTP (including SSE) and STDIO. Configure multiple servers and use a single facade to list/call tools and read resources, with per-request content negotiation.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Install the package:
    composer require redberry/mcp-client-laravel
    
  2. Publish config:
    php artisan vendor:publish --tag="mcp-client-config"
    
  3. Configure a server in config/mcp-client.php (e.g., GitHub Copilot or a local memory server):
    'servers' => [
        'github' => [
            'type'     => \Redberry\MCPClient\Enums\Transporters::HTTP,
            'base_url' => 'https://api.githubcopilot.com/mcp',
            'token'    => env('GITHUB_API_TOKEN'),
        ],
    ],
    

First Use Case: List Tools

use Redberry\MCPClient\Facades\MCPClient;

$tools = MCPClient::connect('github')->tools();
$toolNames = $tools->pluck('name'); // ['search', 'create_issue', ...]

Implementation Patterns

Dependency Injection

Inject the MCPClient contract or facade into services:

use Redberry\MCPClient\Contracts\MCPClient;

class GitHubService {
    public function __construct(private MCPClient $client) {}

    public function listTools() {
        return $this->client->connect('github')->tools();
    }
}

Server-Specific Clients

Cache handles for multiple servers:

$github = MCPClient::connect('github');
$memory = MCPClient::connect('memory');

// Reuse handles; no re-initialization
$github->callTool('search', ['query' => 'laravel']);

Streaming Responses

Observe intermediate events (e.g., logs, progress):

$result = MCPClient::connect('github')
    ->callTool('long_task', ['input' => 'data'], function (array $event) {
        Log::debug('MCP Event:', $event);
    });

Resource Access

Fetch resources by URI:

$fileContent = MCPClient::connect('memory')
    ->readResource('file:///project/src/AppServiceProvider.php');

STDIO Transport (Local Processes)

Configure a local subprocess (e.g., @modelcontextprotocol/server-memory):

'memory' => [
    'type'    => \Redberry\MCPClient\Enums\Transporters::STDIO,
    'command' => ['npx', '-y', '@modelcontextprotocol/server-memory'],
    'cwd'     => base_path(),
],

Gotchas and Tips

Pitfalls

  1. STDIO Transport Limitation:

    • Issue: Fails under php artisan serve (process killed between requests).
    • Fix: Use Octane, Sail, or Valet for local development.
  2. Session Retries:

    • HTTP 404 = expired session. The client auto-retries once (configurable via max_session_retries).
    • Debug Tip: Check mcp-session-id headers in responses.
  3. STDIO Timeouts:

    • timeout (legacy) vs. request_timeout/process_timeout:
      • request_timeout: Wait for response (default: 30s).
      • process_timeout: Kill subprocess (default: null).
    • Fix: Set process_timeout if you need a hard cap.
  4. JSON-RPC id Handling:

    • Gotcha: Omit id for notifications (e.g., notifications/initialized).
    • Debug: Use id_type: 'string' in config if IDs clash with numeric keys.

Debugging

  • Enable Guzzle Middleware (HTTP transport):

    $client = new \GuzzleHttp\Client([
        'handler' => \GuzzleHttp\HandlerStack::create([
            new \GuzzleHttp\Middleware::tap(function ($request) {
                Log::debug('MCP Request:', $request->getBody());
            }),
        ]),
    ]);
    

    Pass via HttpTransporter constructor.

  • STDIO Logs: Capture subprocess output:

    $transporter = new \Redberry\MCPClient\Transporters\StdioTransporter(
        command: ['npx', 'server'],
        cwd: base_path(),
        onOutput: function ($type, $buffer) {
            Log::debug("STDIO [{$type}]:", $buffer);
        }
    );
    

Extension Points

  1. Custom Transports:

    • Implement Redberry\MCPClient\Core\Transporters\Transporter.
    • Register in Transporters::case() enum and TransporterFactory::make().
    • Example: Add a gRPC transporter by extending the interface.
  2. Override Default Client:

    $this->app->bind(\Redberry\MCPClient\Contracts\MCPClient::class, function () {
        return new \Redberry\MCPClient\MCPClient(
            config('mcp-client.servers'),
            new \Your\Custom\TransporterFactory()
        );
    });
    
  3. Stream Parsing:

    • Extend SseStreamParser to handle custom SSE formats.

Configuration Quirks

  • HTTP Headers: Merge additional headers via headers key:
    'headers' => ['X-Custom-Header' => 'value'],
    
  • Token Auth: Always use Authorization: Bearer {token} for HTTP.
  • STDIO Environment: Merge env vars with inherit_env: false to isolate the subprocess.

Performance Tips

  • Reuse Handles: Cache MCPClient::connect('server') to avoid re-initialization.
  • Batch Requests: Use callTool with arrays for parallelizable operations (if supported by the server).
  • Streaming: Prefer onEvent callbacks for large responses to avoid memory spikes.
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/entity-migrator
codraw/doctrine-extra
codraw/aws-tool-kit
codraw/validator
codraw/workflow
codraw/open-api
codraw/cron-job
codraw/process
codraw/log
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