Skip to content

Getting started

Requirements

RequirementVersion
PHP8.3 – 8.5
mcp/sdk~0.7.0 (experimental until 1.0 — hence the tilde pin)
MCP protocol2025-11-25 (the SDK's default; it advertises this in initialize regardless of what the client asks for)
ext-fileinforequired by the SDK

Install

bash
composer require rasuvaeff/yii3-mcp

1. Declare a tool

Tools are ordinary Yii3 services. Capability methods are annotated with the SDK's own attributes — this package invents no protocol structures:

php
use Mcp\Capability\Attribute\McpTool;

final readonly class OrderTools
{
    public function __construct(private OrderRepository $orders) {}

    /**
     * Returns the current status of an order.
     */
    #[McpTool(name: 'order.status')]
    public function status(string $orderId): string
    {
        return $this->orders->get($orderId)->status->value;
    }
}

Input schemas are generated by the SDK from the method signature and DocBlock. #[McpResource], #[McpResourceTemplate] and #[McpPrompt] methods work the same way — see Capabilities for all four.

2. Register it

php
// config/params.php
return [
    'rasuvaeff/yii3-mcp' => [
        'server_name' => 'my-app',
        'server_version' => '1.0.0',
        'tools' => [OrderTools::class],
        'endpoint_secret' => getenv('MCP_SECRET'),
    ],
];

Handlers are registered as [class, method] references — the SDK resolves the instance through the Yii3 container on call, so constructor dependencies are injected the normal way. endpoint_secret is mandatory before the endpoint answers anything: an empty secret makes SharedSecretMiddleware reject every request with an explanatory 503 rather than serve unprotected — see Security.

3. Route the endpoint

php
// config/routes.php
Route::methods(['POST', 'GET', 'DELETE', 'OPTIONS'], '/mcp')
    ->middleware(SharedSecretMiddleware::class)
    ->action(McpAction::class),

An MCP client connects with the secret header:

json
{
    "mcpServers": {
        "my-app": {
            "type": "http",
            "url": "https://example.com/mcp",
            "headers": { "X-Mcp-Secret": "..." }
        }
    }
}

stdio for local development

php
// add McpServeCommand to your console commands
./yii mcp:serve

Claude Code config: claude mcp add my-app -- ./yii mcp:serve.

Check what's actually served

Before pointing a real client at the endpoint, mcp:list prints every registered tool, resource, template and prompt without one — see Operations for the full introspection and diagnostics workflow:

bash
./yii mcp:list
./yii mcp:doctor

Next steps