PHPackages                             ecourty/mcp-server-bundle - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [DevOps &amp; Deployment](/categories/devops)
4. /
5. ecourty/mcp-server-bundle

Abandoned → [symfony/mcp-bundle](/?search=symfony%2Fmcp-bundle)ArchivedSymfony-bundle[DevOps &amp; Deployment](/categories/devops)

ecourty/mcp-server-bundle
=========================

A Symfony Bundle to create MCP servers

1.3.0(9mo ago)503.8k↓20%6[4 PRs](https://github.com/EdouardCourty/mcp-server-bundle/pulls)MITPHPPHP ^8.3CI passing

Since Jun 17Pushed 6mo ago1 watchersCompare

[ Source](https://github.com/EdouardCourty/mcp-server-bundle)[ Packagist](https://packagist.org/packages/ecourty/mcp-server-bundle)[ RSS](/packages/ecourty-mcp-server-bundle/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (6)Dependencies (12)Versions (19)Used By (0)

MCP Server Bundle (Deprecated)
==============================

[](#mcp-server-bundle-deprecated)

Caution

This bundle is deprecated and will no longer receive updates.
Please consider using alternative solutions for MCP server implementations.
I encourage the use of [Symfony AI](https://github.com/symfony/ai) instead.

[![PHP CI](https://github.com/EdouardCourty/mcp-server-bundle/actions/workflows/php_ci.yml/badge.svg)](https://github.com/EdouardCourty/mcp-server-bundle/actions/workflows/php_ci.yml)

A powerful Symfony bundle for handling MCP (Model Context Protocol) server implementations, providing tools for JSON-RPC request handling and tool management.
*Read the [official MCP specification](https://modelcontextprotocol.io/docs/concepts/tools#overview).*

MCP Servers provide the fundamental building blocks for adding context to language models via MCP.
These primitives enable rich interactions between clients, servers, and language models:

- **Prompts**: Pre-defined templates or instructions that guide language model interactions
- **Resources**: Structured data or content that provides additional context to the model
- **Tools**: Executable functions that allow models to perform actions or retrieve information

The current MCP protocol supported version is `2025-06-18`, which is the latest stable version as of June 2025.

Warning

The specification of the Model Context Protocol (MCP) changes frequently. This bundle will evolve along with the specification, so please ensure you are using the latest version of the bundle.
The CHANGELOG can be found [here](CHANGELOG.md).

Table of Contents
-----------------

[](#table-of-contents)

- [Getting Started](#getting-started)
    - [Installation](#installation)
    - [Configuration](#configuration)
- [Tools](#tools)
    - [Creating Tools](#creating-tools)
    - [Tool Results](#tool-results)
    - [Tool Events](#tool-events)
    - [Input Schema Management](#input-schema-management)
    - [JSON-RPC Integration](#json-rpc-integration)
- [Resources](#resources)
    - [Creating Resources](#creating-resources)
        - [Static Resources](#static-resources)
        - [Templated Resources](#templated-resources)
        - [Multiple Parameters](#multiple-parameters)
        - [Parameter Type Casting](#parameter-type-casting)
    - [Resource Results](#resource-results)
    - [Resource Events](#resource-events)
    - [JSON-RPC Integration](#json-rpc-integration-1)
- [Prompts](#prompts)
    - [Creating Prompts](#creating-prompts)
    - [Prompt Results](#prompt-results)
    - [Prompt Events](#prompt-events)
    - [JSON-RPC Integration](#json-rpc-integration-2)
- [JSON-RPC Methods](#json-rpc-methods)
    - [Built-in Methods](#built-in-methods)
    - [Custom Methods](#custom-methods)
- [Developer Experience](#developer-experience)
- [Contributing](#contributing)
- [License](#license)

Getting Started
---------------

[](#getting-started)

The MCP Server Bundle provides a structured way to create and manage tools that can be used by clients via JSON-RPC requests.
It includes features for MCP tool management, and JSON-RPC method handling.

This bundle is designed to be flexible and extensible, allowing developers to create custom tool handlers and method handlers as needed.
MethodHandlers and ToolHandlers are registered and autowired using attributes, making it easy to define and manage your own tools.

### Installation

[](#installation)

1. Install the MCP Server Bundle via Composer:

```
composer require ecourty/mcp-server-bundle
```

2. Add the bundle to your `config/bundles.php` (if not using Symfony Flex):

```
return [
    // ...
    Ecourty\McpServerBundle\McpServerBundle::class => ['all' => true],
];
```

3. Configure the routes in `config/routes/mcp.yaml`:

```
mcp_controller:
  path: /mcp
  controller: mcp_server.entrypoint_controller
```

### Configuration

[](#configuration)

You can customize the MCP Server Bundle configuration in `config/packages/mcp_server.yaml`:

```
mcp_server:
  server:
    name: 'My MCP Server' # The name of your MCP server, used in the initialization response
    title: 'My MCP Server Display Name' # The title of your MCP server, used in the initialization response
    version: '1.0.0' # The version of your MCP server, used in the initialization response
```

Tools
-----

[](#tools)

Tools are the core components of the MCP Server Bundle. They allow you to define and manage custom logic that can be triggered by clients.

### Creating Tools

[](#creating-tools)

1. Create a new class that will handle your tool logic
2. Use the `#[AsTool]` attribute to register your tool
3. Optionally, define the input schema for your tool using a class with validation constraints and OpenAPI attributes
4. Implement the `__invoke` method to handle the tool logic and return a `ToolResult`

*As Tool classes are services within the Symfony application, any dependency can be injected in it, using the constructor, like any other service.*

Example:

- Tool input schema class:

```
#[OA\Schema(required: ['emailAddress', 'username'])]
class CreateUserSchema
{
    #[Assert\Email]
    #[Assert\NotBlank]
    #[Assert\Length(min: 5, max: 255)]
    #[OA\Property(description: 'The email address of the user', type: 'string', maxLength: 255, minLength: 5, nullable: false)]
    public string $emailAddress;

    #[Assert\NotBlank]
    #[Assert\Length(min: 3, max: 50)]
    #[OA\Property(description: 'The username of the user', type: 'string', maxLength: 50, minLength: 3, nullable: false)]
    public string $username;
}
```

- Tool class:

```
use App\Schema\CreateUserSchema;
use Ecourty\McpServerBundle\Attribute\AsTool;
use Ecourty\McpServerBundle\Attribute\ToolAnnotations;
use Ecourty\McpServerBundle\IO\TextToolResult;
use Ecourty\McpServerBundle\IO\ToolResult;

#[AsTool(
    name: 'create_user', # Unique identifier for the tool, used by clients to call it
    description: 'Creates a new user in the system', # This description is used by LLMs to understand the tool's purpose
    annotations: new ToolAnnotations(
        title: 'Create a user', // A human-readable title for the tool, useful for documentation
        readOnlyHint: false, // Defines the request is not read-only (creates a user)
        destructiveHint: false, // Defines the request is not destructive (does not delete data)
        idempotentHint: false, // Defines the request cannot be repeated without changing the state
        openWorldHint: false, // The tool does not interact with external systems
    )
)]
class CreateUserTool
{
    public function __invoke(CreateUserSchema $createUserSchema): ToolResult
    {
        // Your logic here...
        return new ToolResult([new TextToolResult('User created successfully!')]);
    }
}
```

### Tool Results

[](#tool-results)

The MCP specification states that tool results should consist of an array of objects.
The bundle provides several result types that can be combined in a single `ToolResult` object:

- `TextToolResult`: For text-based results
- `ImageToolResult`: For image results
- `AudioToolResult`: For audio results
- `ResourceToolResult`: For file or resource results

All tool results must be wrapped in a `ToolResult` object, which can contain multiple results and handle error state.

Example:

```
