Skip to content

Symfony AI - Mate Component

Edit this page

The Mate component provides an MCP (Model Context Protocol) server that enables AI assistants to interact with PHP applications (including Symfony) through standardized tools. This is a development tool, not intended for production use.

Installation

1
$ composer require --dev symfony/ai-mate

Purpose

Symfony AI Mate is a development tool that creates a local MCP server to enhance your AI assistant (JetBrains AI, Claude, GitHub Copilot, Cursor, etc.) with specific knowledge about your PHP application and development environment.

Important: This is intended for development and debugging only, not for production deployment.

This is the core package that creates and manages your MCP server. It works with any PHP application - while it includes Symfony-specific tools via bridges, the core functionality is framework-agnostic.

Quick Start

Install with composer:

1
$ composer require --dev symfony/ai-mate

Initialize configuration:

1
$ vendor/bin/mate init

This creates:

  • mate/ directory with configuration files
  • mate/src directory for custom extensions
  • mate/AGENT_INSTRUCTIONS.md placeholder (refreshed by mate discover)
  • mcp.json for MCP clients that support it (e.g. Claude Desktop)
  • bin/codex and bin/codex.bat wrappers for Codex runtime MCP injection

While generating mcp.json, mate init asks which PHP binary the coding agent should use to launch the server. The default is detected from the environment: for a containerized setup where a .ddev/ directory is present, it defaults to ddev exec php so the host-side agent starts Mate inside the container; otherwise it defaults to php. Accept the default or provide your own launch command (for example docker compose exec php php for a plain Docker Compose setup).

It also updates your composer.json with the following configuration:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
{
    "autoload-dev": {
        "psr-4": {
            "Mate\\": "mate/src/"
        }
    },
    "extra": {
        "ai-mate": {
            "extension": false,
            "scan-dirs": ["mate/src"],
            "includes": ["mate/config.php"]
        }
    }
}

The extension: false flag prevents your application from being discovered as a reusable Mate extension when it is installed as a dependency elsewhere. Remove it, or set it to true, only if your package should be discoverable by other projects.

After running mate init, update your autoloader:

1
$ composer dump-autoload

Automatic Discovery

The symfony/ai-mate package installs the optional Composer plugin symfony/ai-mate-composer-plugin. After your project has been initialized and mate/extensions.php exists, Composer automatically runs:

1
$ vendor/bin/mate discover --composer

after composer install and composer update. This refreshes discovered extensions and regenerates the managed instruction artifacts.

Before initialization, the Composer plugin does not modify your project. It only prints a hint to run:

1
$ vendor/bin/mate init

Use vendor/bin/mate discover whenever you want to refresh extensions manually after changing Mate configuration, adding instructions, or working on local extensions.

Discover available extensions:

1
$ vendor/bin/mate discover

This command also refreshes:

  • mate/AGENT_INSTRUCTIONS.md
  • Managed AI Mate instruction section in AGENTS.md

Start the MCP server:

1
$ vendor/bin/mate serve

For Codex, start with the generated wrapper (./bin/codex); Codex does not read this project's mcp.json:

1
$ ./bin/codex

Add Custom Tools

The easiest way to add tools is to create a mate/src folder next to your src and tests directories, then add a class with a method using the #[McpTool] attribute:

1
2
3
4
5
6
7
8
9
10
11
12
13
// mate/MyTool.php
namespace Mate;

use Mcp\Capability\Attribute\McpTool;

class MyTool
{
    #[McpTool(name: 'my_tool', description: 'My custom tool')]
    public function execute(string $param): array
    {
        return ['result' => $param];
    }
}

More about attributes and how to configure Prompts, Resources and more can be found at the MCP SDK documentation.

Configuration

The configuration folder is called mate and is located in your project's root directory. It contains two important files:

  • mate/extensions.php - Enable/disable extensions
  • mate/config.php - Configure settings

Tip

The folder and default configuration is automatically generated by running mate init.

Extensions Configuration

1
2
3
4
5
6
7
8
// mate/extensions.php
// This file is managed by 'mate discover'
// You can manually edit to enable/disable extensions

return [
    'vendor/package-name' => ['enabled' => true],
    'vendor/another-package' => ['enabled' => false],
];

Services Configuration

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// mate/config.php
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;

return static function (ContainerConfigurator $container): void {
    $container->parameters()
        // Override default parameters here
        // ->set('mate.cache_dir', sys_get_temp_dir().'/mate')
        // ->set('mate.env_file', ['.env'])
    ;

    $container->services()
        // Register your custom services here
    ;
};

Disabling Specific Features

Use the MateHelper class to disable specific features:

1
2
3
4
5
6
7
8
use Symfony\AI\Mate\Container\MateHelper;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;

return static function (ContainerConfigurator $container): void {
    MateHelper::disableFeatures($container, [
        'symfony/ai-mate' => ['server-info'],
    ]);
};

Environment Variables

Use %env(VAR_NAME)% syntax in service configuration to reference environment variables. See the Symfony documentation on environment variables for more information.

Adding Third-Party Extensions

  1. Install the package:

    1
    $ composer require vendor/symfony-tools
  2. Discover available tools (auto-generates/updates mate/extensions.php):

    1
    $ vendor/bin/mate discover

    When the project has already been initialized, Composer also refreshes discovery automatically after composer install and composer update.

  3. Optionally disable specific extensions:

    1
    2
    3
    4
    5
    // mate/extensions.php
    return [
        'vendor/symfony-tools' => ['enabled' => true],
        'vendor/unwanted-tools' => ['enabled' => false],
    ];

To create a third party extension, see Creating MCP Extensions.

Available Bridges

Symfony Bridge

The Symfony bridge (symfony/ai-symfony-mate-extension) provides container introspection and profiler data access tools for Symfony applications.

Container Introspection

MCP Tools:

  • symfony-services - List Symfony services from the compiled container and optionally filter by service ID or class name using the query parameter

Configuration:

Configure the cache directory:

1
2
$container->parameters()
    ->set('ai_mate_symfony.cache_dir', '%mate.root_dir%/var/cache');

Troubleshooting:

Container not found:

Ensure the cache directory parameter points to the correct location. The bridge looks for compiled container XML files in the cache directory, including kernels with custom class names.

Services not appearing:

  1. Clear Symfony cache: bin/console cache:clear
  2. Ensure the container is compiled (warm up cache)
  3. Verify the container XML file exists in the cache directory

Profiler Data Access

When symfony/http-kernel and symfony/web-profiler-bundle are installed, profiler tools become available for accessing Symfony profiler data.

MCP Tools:

  • symfony-profiler-list - List available profiler profiles with summary data, supports filtering by date range (from/to parameters) and limiting results (use limit: 1 for the latest profile)
  • symfony-profiler-get - Get a specific profile by token

All tools return profiles with a resource_uri field that points to the full profile resource.

MCP Resources:

  • symfony-profiler://profile/{token} - Full profile details including metadata and list of available collectors with URIs
  • symfony-profiler://profile/{token}/{collector} - Detailed collector-specific data (request, response, exception, events, etc.)

When the related dependencies are installed, collector data is normalized for AI consumption for:

  • Doctrine DBAL queries
  • Symfony Mailer messages
  • Symfony Translation usage

If no formatter is registered for a collector, Mate falls back to exposing the collector's raw data.

Configuration:

Single profiler directory (default):

1
2
$container->parameters()
    ->set('ai_mate_symfony.profiler_dir', '%mate.root_dir%/var/cache/dev/profiler');

Multiple directories with contexts (e.g., for multi-kernel applications):

1
2
3
4
5
$container->parameters()
    ->set('ai_mate_symfony.profiler_dir', [
        'website' => '%mate.root_dir%/var/cache/website/dev/profiler',
        'admin' => '%mate.root_dir%/var/cache/admin/dev/profiler',
    ]);

When using multiple directories, profiles include a context field for filtering.

Example Usage:

Search for errors:

1
2
3
4
5
6
7
8
9
10
11
// Using symfony-profiler-list tool
{
    "method": "tools/call",
    "params": {
        "name": "symfony-profiler-list",
        "arguments": {
            "statusCode": 500,
            "limit": 20
        }
    }
}

Access full profile via resource:

1
2
3
4
5
6
7
// Using resource template
{
    "method": "resources/read",
    "params": {
        "uri": "symfony-profiler://profile/abc123"
    }
}

Access specific collector:

1
2
3
4
5
6
{
    "method": "resources/read",
    "params": {
        "uri": "symfony-profiler://profile/abc123/exception"
    }
}

Security:

Cookies, session data, authentication headers, and sensitive environment variables are automatically redacted from profiler data.

Extensibility:

Create custom collector formatters by implementing CollectorFormatterInterface and registering via DI tag ai_mate_symfony.profiler_collector_formatter.

Troubleshooting:

Profiles not found:

  1. Ensure the profiler directory parameter points to the correct location
  2. Verify Symfony profiler is enabled in your environment
  3. Generate some HTTP requests to create profile data

Collector data not available:

  1. Check that the specific collector is enabled in Symfony profiler configuration
  2. Verify the profile was captured with that collector active

Monolog Bridge

The Monolog bridge (symfony/ai-monolog-mate-extension) provides log search and analysis tools:

  • monolog-search - Search log entries by text term with optional filters (supports regex parameter for regex patterns and level filter)
  • monolog-context-search - Search logs by context field value
  • monolog-tail - Get the last N log entries
  • monolog-list-files - List available log files
  • monolog-list-channels - List all log channels

Configure the log directory:

1
2
$container->parameters()
    ->set('ai_mate_monolog.log_dir', '%mate.root_dir%/var/log');

Troubleshooting

Logs not found:

Ensure the log directory parameter points to the correct location where your Monolog log files are stored.

Log parsing errors:

  1. Verify log format is standard Monolog line format or JSON
  2. Check file permissions on log files
  3. Ensure log files are not empty or corrupted

Built-in Tools

The core package provides basic system information tools:

  • server-info - Get PHP runtime environment details: version, OS, OS family, and loaded extensions

Commands

mate init
Initialize AI Mate configuration and create the mate/ directory.
mate discover

Scan for MCP extensions in installed packages. This command will:

  • Scan your vendor directory for packages with extra.ai-mate configuration
  • Generate or update mate/extensions.php with discovered extensions
  • Preserve existing enabled/disabled states for known extensions
  • Default new extensions to enabled
mate serve
Start the MCP server with stdio transport.
mate clear-cache
Clear the MCP server cache.
mate debug:capabilities

Display all discovered MCP capabilities grouped by extension. This command is useful for:

  • Verifying extension installation and capability registration
  • Debugging missing or misconfigured extensions
  • Understanding which package provides each capability
  • Inspecting available tools during development

Options:

--format=FORMAT
Output format: text (default), json, or toon. The toon format requires helgesverre/toon.
--extension=EXTENSION
Filter by extension package name (e.g., symfony/ai-monolog-mate-extension)
--type=TYPE
Filter by capability type: tool, resource, prompt, or template

Examples:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# Show all capabilities
$ vendor/bin/mate debug:capabilities

# Show only tools
$ vendor/bin/mate debug:capabilities --type=tool

# Show capabilities from specific extension
$ vendor/bin/mate debug:capabilities --extension=symfony/ai-monolog-mate-extension

# JSON output for scripting
$ vendor/bin/mate debug:capabilities --format=json

# TOON output for token-efficient inspection
$ vendor/bin/mate debug:capabilities --format=toon

# Root project capabilities
$ vendor/bin/mate debug:capabilities --extension=_custom
mate debug:extensions

Display detailed information about discovered and loaded MCP extensions. This command is useful for:

  • Understanding which extensions are discovered vs enabled vs loaded
  • Debugging extension loading issues
  • Verifying extension configuration from mate/extensions.php
  • Inspecting scan directories and include files
  • Troubleshooting why an extension isn't providing capabilities

Status Indicators:

[enabled]
Extension is configured to load in mate/extensions.php
[loaded]
Extension successfully loaded into the DI container
[not loaded]
Extension failed to load (package removed, error, etc.) - useful for troubleshooting

Options:

--format=FORMAT
Output format: text (default), json, or toon. The toon format requires helgesverre/toon.
--show-all
Show all discovered extensions including disabled ones

Examples:

1
2
3
4
5
6
7
8
9
10
11
# Show enabled extensions
$ vendor/bin/mate debug:extensions

# Show all extensions (including disabled)
$ vendor/bin/mate debug:extensions --show-all

# JSON output for scripting
$ vendor/bin/mate debug:extensions --format=json

# TOON output for token-efficient inspection
$ vendor/bin/mate debug:extensions --format=toon
mate mcp:tools:list

List all available MCP tools with their metadata. This command provides a compact overview of tools for quick reference and filtering.

Options:

--filter=PATTERN
Filter tools by name pattern (supports wildcards like search* or *logs)
--extension=EXTENSION
Filter tools by extension package name
--format=FORMAT
Output format: table (default), json, or toon. The toon format requires helgesverre/toon.

Examples:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# List all tools
$ vendor/bin/mate mcp:tools:list

# Filter by name pattern
$ vendor/bin/mate mcp:tools:list --filter="monolog*"
$ vendor/bin/mate mcp:tools:list --filter="*search"

# Show tools from specific extension
$ vendor/bin/mate mcp:tools:list --extension=symfony/ai-monolog-mate-extension

# JSON output for scripting
$ vendor/bin/mate mcp:tools:list --format=json

# TOON output for token-efficient inspection
$ vendor/bin/mate mcp:tools:list --format=toon

# Combined filters
$ vendor/bin/mate mcp:tools:list --extension=symfony/ai-monolog-mate-extension --filter="*search"
mate mcp:tools:inspect

Display detailed information about a specific MCP tool including its full JSON schema. This command is useful for understanding tool parameters and requirements.

Arguments:

tool-name
Name of the tool to inspect (required)

Options:

--format=FORMAT
Output format: text (default), json, or toon. The toon format requires helgesverre/toon.

Examples:

1
2
3
4
5
6
7
8
9
10
11
# Inspect a specific tool
$ vendor/bin/mate mcp:tools:inspect server-info

# Inspect extension tool
$ vendor/bin/mate mcp:tools:inspect monolog-search

# JSON output for scripting
$ vendor/bin/mate mcp:tools:inspect server-info --format=json

# TOON output for token-efficient inspection
$ vendor/bin/mate mcp:tools:inspect server-info --format=toon
mate mcp:tools:call

Execute MCP tools via JSON input parameters. This command allows you to test and debug tools by executing them directly from the command line.

Arguments:

tool-name
Name of the tool to execute (required)
json-input
JSON object with tool parameters (required)

Options:

--format=FORMAT
Output format: pretty (default), json, or toon. The toon format requires helgesverre/toon.

Examples:

1
2
3
4
5
6
7
8
9
10
11
# Execute tool with empty parameters
$ vendor/bin/mate mcp:tools:call server-info '{}'

# Execute tool with parameters
$ vendor/bin/mate mcp:tools:call monolog-search '{"term": "error", "level": "error"}'

# JSON output format
$ vendor/bin/mate mcp:tools:call server-info '{}' --format=json

# TOON output for token-efficient inspection
$ vendor/bin/mate mcp:tools:call server-info '{}' --format=toon

Security

Discovered extensions are written to mate/extensions.php and new entries default to enabled: true. Disable specific packages by setting their enabled flag to false.

Packages that set extra.ai-mate.extension to false are excluded from discovery entirely.

This work, including the code samples, is licensed under a Creative Commons BY-SA 3.0 license.
TOC
    Version