Skip to main content

Overview

The Model Context Protocol (MCP) integration enables your Agents to dynamically discover and use tools and resources provided by external MCP servers. This powerful feature allows you to extend your agent’s capabilities without writing custom tool implementations.
MCP support is provided through the redberry/mcp-client-laravel package, which is included as a dependency.

Configuration

Configure MCP servers in your config/laragent.php file under the mcp_servers key. LarAgent supports two transport types: HTTP and STDIO.

HTTP Transport

Use HTTP transport for MCP servers accessible via HTTP endpoints:
config/laragent.php
'mcp_servers' => [
    'github' => [
        'type' => \Redberry\MCPClient\Enums\Transporters::HTTP,
        'base_url' => 'https://api.githubcopilot.com/mcp',
        'timeout' => 30,
        'token' => env('GITHUB_API_TOKEN', null),
    ],
],

STDIO Transport

Use STDIO transport for command-line MCP servers:
config/laragent.php
'mcp_servers' => [
    'mcp_server_memory' => [
        'type' => \Redberry\MCPClient\Enums\Transporters::STDIO,
        'command' => [
            'npx',
            '-y',
            '@modelcontextprotocol/server-memory',
        ],
        'timeout' => 30,
        'cwd' => base_path(),
    ],
],
You can configure multiple MCP servers simultaneously by adding more entries to the mcp_servers array.

Registering MCP Servers in Agents

Once configured, register MCP servers in your agent class using either a property or a method.

Using Property

The simplest approach is to define the $mcpServers property:
use LarAgent\Agent;

class MyAgent extends Agent
{
    protected $mcpServers = [
        'github',
        'mcp_server_memory',
    ];
}

Using Method

For more control and dynamic nature, implement the registerMcpServers() method:
use LarAgent\Agent;

class MyAgent extends Agent
{
    public function registerMcpServers()
    {
        return [
            'github',
            'mcp_server_memory',
        ];
    }
}

Filtering Tools and Resources

By default, LarAgent fetches only tools from MCP servers. You can explicitly control what to fetch using filters.

Fetch Specific Types

Use the :tools or :resources suffix to specify what to fetch:
protected $mcpServers = [
    'mcp_server_memory:tools',
    'mcp_everything:resources',
];

Include/Exclude Specific Items

Use only and except filters to control which tools or resources are registered:
public function registerMcpServers()
{
    return [
        'github:tools|only:search_repositories,get_issues',
    ];
}
When using filters, separate multiple items with commas and ensure there are no spaces after the commas.

Working with Resources

Resources are data sources provided by MCP servers. While tools are automatically registered, resources need to be explicitly requested via "mcp_server_name:resources". Alternatively, resources and tools can be accessed manually through the mcpClient property.

Manual Resource Access

Access resources directly in your agent methods:
use LarAgent\Agent;

class MyAgent extends Agent
{
    protected $mcpServers = ['mcp_everything'];

    public function instructions()
    {
        // Read a resource from the MCP server
        $resourceData = $this->mcpClient
            ->connect('mcp_everything')
            ->readResource('test://static/resource/1');

        // Use resource data in your instructions
        $context = $resourceData['contents'][0]['text'];

        return "You are a helpful assistant. Context: {$context}";
    }
}

Resource Response Structure

The readResource() method returns an array with the following structure:
[
    "contents" => [
        [
            "uri" => "test://static/resource/1",
            "name" => "Resource 1",
            "mimeType" => "text/plain",
            "text" => "Resource 1: This is a plaintext resource"
        ]
    ]
]
contents
array
Array containing resource content objects.

Registering Resources as Tools

You can make resources available as tools by explicitly requesting them:
protected $mcpServers = [
    'mcp_everything:resources',
];
When registered this way, resources become callable tools that your agent can use during conversations. Description of resource is appended with “Read the resource: ”. So, if resource description is “Revenue report 2025”, the tool description will be: “Read the resource: Revenue report 2025”

Manual Tool Access

You can run MCP tools manually via mcpClient property and callTool method:

#[Tool("Get issue details from LarAgent repository")]
public function readTheIssue(int $issue_number) {
    $args = [
      "issue_number" => $issue_number,
      "owner" => "maestroerror",
      "repo" => "LarAgent"
    ];
    return $this->mcpClient->connect("github")->callTool("get_issue", $args);
}

This way, you can write your own descriptions to the MCP tools, also hard-code/restrict the arguments while making the error surface smaller. In this example above, if I am building an agent to work only with LarAgent issues, why should LLM generate the same “owner” and “repo” parameters for MCP tool each time? They are the static and should be in every request.

How MCP Tools Work

MCP tools are dynamically constructed based on metadata from the MCP server:
1

Discovery

LarAgent connects to the configured MCP server and retrieves available tools and their schemas.
2

Registration

Tools are automatically registered with your agent, including their parameters, descriptions, and required fields.
3

Execution

When the LLM decides to use an MCP tool, LarAgent handles the invocation and returns results to the conversation.
MCP tools integrate seamlessly with your agent’s existing tool system, appearing alongside custom tools.
Initialization -> fetching -> registration of tools: The process is pretty intensive, using more than 3 mcp servers per Agent can dramatically decrease the performance / response time

Complete Example

Here’s a comprehensive example combining multiple MCP servers with filtering:
<?php

namespace App\Agents;

use LarAgent\Agent;

class ResearchAgent extends Agent
{
    protected $model = 'gpt-4';

    public function registerMcpServers()
    {
        return [
            // Get all tools from GitHub MCP server
            'github:tools',

            // Get memory tools but exclude delete operations
            'mcp_server_memory:tools|except:delete_entities,delete_observations',

            // Get specific resources
            'knowledge_base:resources|only:docs,api_reference',
        ];
    }

    public function instructions()
    {
        // Load additional context from a resource
        $apiDocs = $this->mcpClient
            ->connect('knowledge_base')
            ->readResource('docs://api_reference');

        $context = $apiDocs['contents'][0]['text'] ?? '';

        return "You are a research assistant with access to GitHub and memory storage.
                Use the available tools to search repositories, track information, and
                answer questions. API Reference: {$context}";
    }
}

Best Practices

  • Use HTTP transport for cloud-based or remote MCP servers
  • Use STDIO transport for local command-line tools and npm packages
  • Consider timeout values based on expected response times
Use except to exclude dangerous or unnecessary operations (like delete functions). Use only when you need a specific subset of tools for focused agents. Start with all tools and refine based on actual usage patterns
Always use environment variables for API tokens and sensitive credentials; Never hardcode tokens directly in configuration files; Review MCP server documentation for required authentication
  • Load resources in instructions() when context is needed
  • Cache resource data when appropriate to avoid repeated fetches
  • Consider resource size impact on token usage

Troubleshooting

Ensure MCP server commands are available in your environment. For STDIO transport with npm packages, verify Node.js and npm/npx are installed and accessible.
For HTTP transport:
  • Verify the base_url is correct and accessible
  • Check authentication tokens are valid
  • Ensure firewall rules allow outbound connections
For STDIO transport:
  • Confirm the command exists (npx, node, etc.)
  • Verify the working directory (cwd) has proper permissions
  • Check the command array syntax is correct
Tools and other issues:
  • Verify the MCP server name matches your configuration exactly
  • Check filter syntax if using only or except
  • Ensure the MCP server actually provides tools (not just resources)
  • Review logs for connection or parsing errors
  • Increase the timeout value in your MCP server configuration
  • For STDIO servers, ensure the command starts quickly
  • Consider network latency for HTTP servers
I